blob: 61c980193c10c0a8cc32cf9eec3807c2ad8298fa [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Motion Eye video4linux driver for Sony Vaio PictureBook
3 *
4 * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
5 *
Jan Engelhardt96de0e22007-10-19 23:21:04 +02006 * Copyright (C) 2001-2002 AlcĂ´ve <www.alcove.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 *
8 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
9 *
10 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
11 *
12 * Some parts borrowed from various video4linux drivers, especially
13 * bttv-driver.c and zoran.c, see original files for credits.
14 *
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.
19 *
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.
24 *
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.
28 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/module.h>
30#include <linux/pci.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/init.h>
32#include <linux/videodev.h>
Mauro Carvalho Chehab5e87efa2006-06-05 10:26:32 -030033#include <media/v4l2-common.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <asm/uaccess.h>
35#include <asm/io.h>
36#include <linux/delay.h>
37#include <linux/interrupt.h>
38#include <linux/vmalloc.h>
Tobias Klauserd013a062005-09-06 15:17:07 -070039#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
41#include "meye.h"
42#include <linux/meye.h>
43
44MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
45MODULE_DESCRIPTION("v4l/v4l2 driver for the MotionEye camera");
46MODULE_LICENSE("GPL");
47MODULE_VERSION(MEYE_DRIVER_VERSION);
48
49/* force usage of V4L1 API */
50static int forcev4l1; /* = 0 */
51module_param(forcev4l1, int, 0644);
52MODULE_PARM_DESC(forcev4l1, "force use of V4L1 instead of V4L2");
53
54/* number of grab buffers */
55static unsigned int gbuffers = 2;
56module_param(gbuffers, int, 0444);
57MODULE_PARM_DESC(gbuffers, "number of capture buffers, default is 2 (32 max)");
58
59/* size of a grab buffer */
60static unsigned int gbufsize = MEYE_MAX_BUFSIZE;
61module_param(gbufsize, int, 0444);
62MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 614400"
63 " (will be rounded up to a page multiple)");
64
65/* /dev/videoX registration number */
66static int video_nr = -1;
67module_param(video_nr, int, 0444);
68MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)");
69
70/* driver structure - only one possible */
71static struct meye meye;
72
73/****************************************************************************/
74/* Memory allocation routines (stolen from bttv-driver.c) */
75/****************************************************************************/
76static void *rvmalloc(unsigned long size)
77{
78 void *mem;
79 unsigned long adr;
80
81 size = PAGE_ALIGN(size);
82 mem = vmalloc_32(size);
83 if (mem) {
84 memset(mem, 0, size);
85 adr = (unsigned long) mem;
86 while (size > 0) {
87 SetPageReserved(vmalloc_to_page((void *)adr));
88 adr += PAGE_SIZE;
89 size -= PAGE_SIZE;
90 }
91 }
92 return mem;
93}
94
95static void rvfree(void * mem, unsigned long size)
96{
97 unsigned long adr;
98
99 if (mem) {
100 adr = (unsigned long) mem;
101 while ((long) size > 0) {
102 ClearPageReserved(vmalloc_to_page((void *)adr));
103 adr += PAGE_SIZE;
104 size -= PAGE_SIZE;
105 }
106 vfree(mem);
107 }
108}
109
110/*
111 * return a page table pointing to N pages of locked memory
112 *
113 * NOTE: The meye device expects DMA addresses on 32 bits, we build
114 * a table of 1024 entries = 4 bytes * 1024 = 4096 bytes.
115 */
116static int ptable_alloc(void)
117{
118 u32 *pt;
119 int i;
120
121 memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
122
123 /* give only 32 bit DMA addresses */
Tobias Klauserd013a062005-09-06 15:17:07 -0700124 if (dma_set_mask(&meye.mchip_dev->dev, DMA_32BIT_MASK))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 return -1;
126
127 meye.mchip_ptable_toc = dma_alloc_coherent(&meye.mchip_dev->dev,
128 PAGE_SIZE,
129 &meye.mchip_dmahandle,
130 GFP_KERNEL);
131 if (!meye.mchip_ptable_toc) {
132 meye.mchip_dmahandle = 0;
133 return -1;
134 }
135
136 pt = meye.mchip_ptable_toc;
137 for (i = 0; i < MCHIP_NB_PAGES; i++) {
138 dma_addr_t dma;
139 meye.mchip_ptable[i] = dma_alloc_coherent(&meye.mchip_dev->dev,
140 PAGE_SIZE,
141 &dma,
142 GFP_KERNEL);
143 if (!meye.mchip_ptable[i]) {
144 int j;
145 pt = meye.mchip_ptable_toc;
146 for (j = 0; j < i; ++j) {
147 dma = (dma_addr_t) *pt;
148 dma_free_coherent(&meye.mchip_dev->dev,
149 PAGE_SIZE,
150 meye.mchip_ptable[j], dma);
151 pt++;
152 }
153 dma_free_coherent(&meye.mchip_dev->dev,
154 PAGE_SIZE,
155 meye.mchip_ptable_toc,
156 meye.mchip_dmahandle);
157 meye.mchip_ptable_toc = NULL;
158 meye.mchip_dmahandle = 0;
159 return -1;
160 }
161 *pt = (u32) dma;
162 pt++;
163 }
164 return 0;
165}
166
167static void ptable_free(void)
168{
169 u32 *pt;
170 int i;
171
172 pt = meye.mchip_ptable_toc;
173 for (i = 0; i < MCHIP_NB_PAGES; i++) {
174 dma_addr_t dma = (dma_addr_t) *pt;
175 if (meye.mchip_ptable[i])
176 dma_free_coherent(&meye.mchip_dev->dev,
177 PAGE_SIZE,
178 meye.mchip_ptable[i], dma);
179 pt++;
180 }
181
182 if (meye.mchip_ptable_toc)
183 dma_free_coherent(&meye.mchip_dev->dev,
184 PAGE_SIZE,
185 meye.mchip_ptable_toc,
186 meye.mchip_dmahandle);
187
188 memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
189 meye.mchip_ptable_toc = NULL;
190 meye.mchip_dmahandle = 0;
191}
192
193/* copy data from ptable into buf */
194static void ptable_copy(u8 *buf, int start, int size, int pt_pages)
195{
196 int i;
197
198 for (i = 0; i < (size / PAGE_SIZE) * PAGE_SIZE; i += PAGE_SIZE) {
199 memcpy(buf + i, meye.mchip_ptable[start++], PAGE_SIZE);
200 if (start >= pt_pages)
201 start = 0;
202 }
203 memcpy(buf + i, meye.mchip_ptable[start], size % PAGE_SIZE);
204}
205
206/****************************************************************************/
207/* JPEG tables at different qualities to load into the VRJ chip */
208/****************************************************************************/
209
210/* return a set of quantisation tables based on a quality from 1 to 10 */
211static u16 *jpeg_quantisation_tables(int *length, int quality)
212{
213 static u16 jpeg_tables[][70] = { {
214 0xdbff, 0x4300, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
215 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
216 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
217 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
218 0xffff, 0xffff, 0xffff,
219 0xdbff, 0x4300, 0xff01, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
220 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
221 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
222 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
223 0xffff, 0xffff, 0xffff,
224 },
225 {
226 0xdbff, 0x4300, 0x5000, 0x3c37, 0x3c46, 0x5032, 0x4146, 0x5a46,
227 0x5055, 0x785f, 0x82c8, 0x6e78, 0x786e, 0xaff5, 0x91b9, 0xffc8,
228 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
229 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
230 0xffff, 0xffff, 0xffff,
231 0xdbff, 0x4300, 0x5501, 0x5a5a, 0x6978, 0xeb78, 0x8282, 0xffeb,
232 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
233 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
234 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
235 0xffff, 0xffff, 0xffff,
236 },
237 {
238 0xdbff, 0x4300, 0x2800, 0x1e1c, 0x1e23, 0x2819, 0x2123, 0x2d23,
239 0x282b, 0x3c30, 0x4164, 0x373c, 0x3c37, 0x587b, 0x495d, 0x9164,
240 0x9980, 0x8f96, 0x8c80, 0xa08a, 0xe6b4, 0xa0c3, 0xdaaa, 0x8aad,
241 0xc88c, 0xcbff, 0xeeda, 0xfff5, 0xffff, 0xc19b, 0xffff, 0xfaff,
242 0xe6ff, 0xfffd, 0xfff8,
243 0xdbff, 0x4300, 0x2b01, 0x2d2d, 0x353c, 0x763c, 0x4141, 0xf876,
244 0x8ca5, 0xf8a5, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
245 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
246 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
247 0xf8f8, 0xf8f8, 0xfff8,
248 },
249 {
250 0xdbff, 0x4300, 0x1b00, 0x1412, 0x1417, 0x1b11, 0x1617, 0x1e17,
251 0x1b1c, 0x2820, 0x2b42, 0x2528, 0x2825, 0x3a51, 0x303d, 0x6042,
252 0x6555, 0x5f64, 0x5d55, 0x6a5b, 0x9978, 0x6a81, 0x9071, 0x5b73,
253 0x855d, 0x86b5, 0x9e90, 0xaba3, 0xabad, 0x8067, 0xc9bc, 0xa6ba,
254 0x99c7, 0xaba8, 0xffa4,
255 0xdbff, 0x4300, 0x1c01, 0x1e1e, 0x2328, 0x4e28, 0x2b2b, 0xa44e,
256 0x5d6e, 0xa46e, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
257 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
258 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
259 0xa4a4, 0xa4a4, 0xffa4,
260 },
261 {
262 0xdbff, 0x4300, 0x1400, 0x0f0e, 0x0f12, 0x140d, 0x1012, 0x1712,
263 0x1415, 0x1e18, 0x2132, 0x1c1e, 0x1e1c, 0x2c3d, 0x242e, 0x4932,
264 0x4c40, 0x474b, 0x4640, 0x5045, 0x735a, 0x5062, 0x6d55, 0x4556,
265 0x6446, 0x6588, 0x776d, 0x817b, 0x8182, 0x604e, 0x978d, 0x7d8c,
266 0x7396, 0x817e, 0xff7c,
267 0xdbff, 0x4300, 0x1501, 0x1717, 0x1a1e, 0x3b1e, 0x2121, 0x7c3b,
268 0x4653, 0x7c53, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
269 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
270 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
271 0x7c7c, 0x7c7c, 0xff7c,
272 },
273 {
274 0xdbff, 0x4300, 0x1000, 0x0c0b, 0x0c0e, 0x100a, 0x0d0e, 0x120e,
275 0x1011, 0x1813, 0x1a28, 0x1618, 0x1816, 0x2331, 0x1d25, 0x3a28,
276 0x3d33, 0x393c, 0x3833, 0x4037, 0x5c48, 0x404e, 0x5744, 0x3745,
277 0x5038, 0x516d, 0x5f57, 0x6762, 0x6768, 0x4d3e, 0x7971, 0x6470,
278 0x5c78, 0x6765, 0xff63,
279 0xdbff, 0x4300, 0x1101, 0x1212, 0x1518, 0x2f18, 0x1a1a, 0x632f,
280 0x3842, 0x6342, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
281 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
282 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
283 0x6363, 0x6363, 0xff63,
284 },
285 {
286 0xdbff, 0x4300, 0x0d00, 0x0a09, 0x0a0b, 0x0d08, 0x0a0b, 0x0e0b,
287 0x0d0e, 0x130f, 0x1520, 0x1213, 0x1312, 0x1c27, 0x171e, 0x2e20,
288 0x3129, 0x2e30, 0x2d29, 0x332c, 0x4a3a, 0x333e, 0x4636, 0x2c37,
289 0x402d, 0x4157, 0x4c46, 0x524e, 0x5253, 0x3e32, 0x615a, 0x505a,
290 0x4a60, 0x5251, 0xff4f,
291 0xdbff, 0x4300, 0x0e01, 0x0e0e, 0x1113, 0x2613, 0x1515, 0x4f26,
292 0x2d35, 0x4f35, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
293 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
294 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
295 0x4f4f, 0x4f4f, 0xff4f,
296 },
297 {
298 0xdbff, 0x4300, 0x0a00, 0x0707, 0x0708, 0x0a06, 0x0808, 0x0b08,
299 0x0a0a, 0x0e0b, 0x1018, 0x0d0e, 0x0e0d, 0x151d, 0x1116, 0x2318,
300 0x251f, 0x2224, 0x221f, 0x2621, 0x372b, 0x262f, 0x3429, 0x2129,
301 0x3022, 0x3141, 0x3934, 0x3e3b, 0x3e3e, 0x2e25, 0x4944, 0x3c43,
302 0x3748, 0x3e3d, 0xff3b,
303 0xdbff, 0x4300, 0x0a01, 0x0b0b, 0x0d0e, 0x1c0e, 0x1010, 0x3b1c,
304 0x2228, 0x3b28, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
305 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
306 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
307 0x3b3b, 0x3b3b, 0xff3b,
308 },
309 {
310 0xdbff, 0x4300, 0x0600, 0x0504, 0x0506, 0x0604, 0x0506, 0x0706,
311 0x0607, 0x0a08, 0x0a10, 0x090a, 0x0a09, 0x0e14, 0x0c0f, 0x1710,
312 0x1814, 0x1718, 0x1614, 0x1a16, 0x251d, 0x1a1f, 0x231b, 0x161c,
313 0x2016, 0x202c, 0x2623, 0x2927, 0x292a, 0x1f19, 0x302d, 0x282d,
314 0x2530, 0x2928, 0xff28,
315 0xdbff, 0x4300, 0x0701, 0x0707, 0x080a, 0x130a, 0x0a0a, 0x2813,
316 0x161a, 0x281a, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
317 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
318 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
319 0x2828, 0x2828, 0xff28,
320 },
321 {
322 0xdbff, 0x4300, 0x0300, 0x0202, 0x0203, 0x0302, 0x0303, 0x0403,
323 0x0303, 0x0504, 0x0508, 0x0405, 0x0504, 0x070a, 0x0607, 0x0c08,
324 0x0c0a, 0x0b0c, 0x0b0a, 0x0d0b, 0x120e, 0x0d10, 0x110e, 0x0b0e,
325 0x100b, 0x1016, 0x1311, 0x1514, 0x1515, 0x0f0c, 0x1817, 0x1416,
326 0x1218, 0x1514, 0xff14,
327 0xdbff, 0x4300, 0x0301, 0x0404, 0x0405, 0x0905, 0x0505, 0x1409,
328 0x0b0d, 0x140d, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
329 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
330 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
331 0x1414, 0x1414, 0xff14,
332 },
333 {
334 0xdbff, 0x4300, 0x0100, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
335 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
336 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
337 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
338 0x0101, 0x0101, 0xff01,
339 0xdbff, 0x4300, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
340 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
341 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
342 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
343 0x0101, 0x0101, 0xff01,
344 } };
345
346 if (quality < 0 || quality > 10) {
347 printk(KERN_WARNING
348 "meye: invalid quality level %d - using 8\n", quality);
349 quality = 8;
350 }
351
352 *length = ARRAY_SIZE(jpeg_tables[quality]);
353 return jpeg_tables[quality];
354}
355
356/* return a generic set of huffman tables */
357static u16 *jpeg_huffman_tables(int *length)
358{
359 static u16 tables[] = {
360 0xC4FF, 0xB500, 0x0010, 0x0102, 0x0303, 0x0402, 0x0503, 0x0405,
361 0x0004, 0x0100, 0x017D, 0x0302, 0x0400, 0x0511, 0x2112, 0x4131,
362 0x1306, 0x6151, 0x2207, 0x1471, 0x8132, 0xA191, 0x2308, 0xB142,
363 0x15C1, 0xD152, 0x24F0, 0x6233, 0x8272, 0x0A09, 0x1716, 0x1918,
364 0x251A, 0x2726, 0x2928, 0x342A, 0x3635, 0x3837, 0x3A39, 0x4443,
365 0x4645, 0x4847, 0x4A49, 0x5453, 0x5655, 0x5857, 0x5A59, 0x6463,
366 0x6665, 0x6867, 0x6A69, 0x7473, 0x7675, 0x7877, 0x7A79, 0x8483,
367 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 0xA29A,
368 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8,
369 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 0xD7D6,
370 0xD9D8, 0xE1DA, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xF1EA, 0xF3F2,
371 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
372 0xC4FF, 0xB500, 0x0011, 0x0102, 0x0402, 0x0304, 0x0704, 0x0405,
373 0x0004, 0x0201, 0x0077, 0x0201, 0x1103, 0x0504, 0x3121, 0x1206,
374 0x5141, 0x6107, 0x1371, 0x3222, 0x0881, 0x4214, 0xA191, 0xC1B1,
375 0x2309, 0x5233, 0x15F0, 0x7262, 0x0AD1, 0x2416, 0xE134, 0xF125,
376 0x1817, 0x1A19, 0x2726, 0x2928, 0x352A, 0x3736, 0x3938, 0x433A,
377 0x4544, 0x4746, 0x4948, 0x534A, 0x5554, 0x5756, 0x5958, 0x635A,
378 0x6564, 0x6766, 0x6968, 0x736A, 0x7574, 0x7776, 0x7978, 0x827A,
379 0x8483, 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998,
380 0xA29A, 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6,
381 0xB9B8, 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4,
382 0xD7D6, 0xD9D8, 0xE2DA, 0xE4E3, 0xE6E5, 0xE8E7, 0xEAE9, 0xF3F2,
383 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
384 0xC4FF, 0x1F00, 0x0000, 0x0501, 0x0101, 0x0101, 0x0101, 0x0000,
385 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
386 0xFF0B,
387 0xC4FF, 0x1F00, 0x0001, 0x0103, 0x0101, 0x0101, 0x0101, 0x0101,
388 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
389 0xFF0B
390 };
391
392 *length = ARRAY_SIZE(tables);
393 return tables;
394}
395
396/****************************************************************************/
397/* MCHIP low-level functions */
398/****************************************************************************/
399
400/* returns the horizontal capture size */
401static inline int mchip_hsize(void)
402{
403 return meye.params.subsample ? 320 : 640;
404}
405
406/* returns the vertical capture size */
407static inline int mchip_vsize(void)
408{
409 return meye.params.subsample ? 240 : 480;
410}
411
412/* waits for a register to be available */
413static void mchip_sync(int reg)
414{
415 u32 status;
416 int i;
417
418 if (reg == MCHIP_MM_FIFO_DATA) {
419 for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
420 status = readl(meye.mchip_mmregs +
421 MCHIP_MM_FIFO_STATUS);
422 if (!(status & MCHIP_MM_FIFO_WAIT)) {
423 printk(KERN_WARNING "meye: fifo not ready\n");
424 return;
425 }
426 if (status & MCHIP_MM_FIFO_READY)
427 return;
428 udelay(1);
429 }
430 } else if (reg > 0x80) {
431 u32 mask = (reg < 0x100) ? MCHIP_HIC_STATUS_MCC_RDY
432 : MCHIP_HIC_STATUS_VRJ_RDY;
433 for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
434 status = readl(meye.mchip_mmregs + MCHIP_HIC_STATUS);
435 if (status & mask)
436 return;
437 udelay(1);
438 }
439 } else
440 return;
441 printk(KERN_WARNING
442 "meye: mchip_sync() timeout on reg 0x%x status=0x%x\n",
443 reg, status);
444}
445
446/* sets a value into the register */
447static inline void mchip_set(int reg, u32 v)
448{
449 mchip_sync(reg);
450 writel(v, meye.mchip_mmregs + reg);
451}
452
453/* get the register value */
454static inline u32 mchip_read(int reg)
455{
456 mchip_sync(reg);
457 return readl(meye.mchip_mmregs + reg);
458}
459
460/* wait for a register to become a particular value */
461static inline int mchip_delay(u32 reg, u32 v)
462{
463 int n = 10;
464 while (--n && mchip_read(reg) != v)
465 udelay(1);
466 return n;
467}
468
469/* setup subsampling */
470static void mchip_subsample(void)
471{
472 mchip_set(MCHIP_MCC_R_SAMPLING, meye.params.subsample);
473 mchip_set(MCHIP_MCC_R_XRANGE, mchip_hsize());
474 mchip_set(MCHIP_MCC_R_YRANGE, mchip_vsize());
475 mchip_set(MCHIP_MCC_B_XRANGE, mchip_hsize());
476 mchip_set(MCHIP_MCC_B_YRANGE, mchip_vsize());
477 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
478}
479
480/* set the framerate into the mchip */
481static void mchip_set_framerate(void)
482{
483 mchip_set(MCHIP_HIC_S_RATE, meye.params.framerate);
484}
485
486/* load some huffman and quantisation tables into the VRJ chip ready
487 for JPEG compression */
488static void mchip_load_tables(void)
489{
490 int i;
491 int length;
492 u16 *tables;
493
494 tables = jpeg_huffman_tables(&length);
495 for (i = 0; i < length; i++)
496 writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
497
498 tables = jpeg_quantisation_tables(&length, meye.params.quality);
499 for (i = 0; i < length; i++)
500 writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
501}
502
503/* setup the VRJ parameters in the chip */
504static void mchip_vrj_setup(u8 mode)
505{
506 mchip_set(MCHIP_VRJ_BUS_MODE, 5);
507 mchip_set(MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL, 0x1f);
508 mchip_set(MCHIP_VRJ_PDAT_USE, 1);
509 mchip_set(MCHIP_VRJ_IRQ_FLAG, 0xa0);
510 mchip_set(MCHIP_VRJ_MODE_SPECIFY, mode);
511 mchip_set(MCHIP_VRJ_NUM_LINES, mchip_vsize());
512 mchip_set(MCHIP_VRJ_NUM_PIXELS, mchip_hsize());
513 mchip_set(MCHIP_VRJ_NUM_COMPONENTS, 0x1b);
514 mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_LO, 0xFFFF);
515 mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_HI, 0xFFFF);
516 mchip_set(MCHIP_VRJ_COMP_DATA_FORMAT, 0xC);
517 mchip_set(MCHIP_VRJ_RESTART_INTERVAL, 0);
518 mchip_set(MCHIP_VRJ_SOF1, 0x601);
519 mchip_set(MCHIP_VRJ_SOF2, 0x1502);
520 mchip_set(MCHIP_VRJ_SOF3, 0x1503);
521 mchip_set(MCHIP_VRJ_SOF4, 0x1596);
522 mchip_set(MCHIP_VRJ_SOS, 0x0ed0);
523
524 mchip_load_tables();
525}
526
527/* sets the DMA parameters into the chip */
528static void mchip_dma_setup(dma_addr_t dma_addr)
529{
530 int i;
531
532 mchip_set(MCHIP_MM_PT_ADDR, (u32)dma_addr);
533 for (i = 0; i < 4; i++)
534 mchip_set(MCHIP_MM_FIR(i), 0);
535 meye.mchip_fnum = 0;
536}
537
538/* setup for DMA transfers - also zeros the framebuffer */
539static int mchip_dma_alloc(void)
540{
541 if (!meye.mchip_dmahandle)
542 if (ptable_alloc())
543 return -1;
544 return 0;
545}
546
547/* frees the DMA buffer */
548static void mchip_dma_free(void)
549{
550 if (meye.mchip_dmahandle) {
551 mchip_dma_setup(0);
552 ptable_free();
553 }
554}
555
556/* stop any existing HIC action and wait for any dma to complete then
557 reset the dma engine */
558static void mchip_hic_stop(void)
559{
560 int i, j;
561
562 meye.mchip_mode = MCHIP_HIC_MODE_NOOP;
563 if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY))
564 return;
565 for (i = 0; i < 20; ++i) {
566 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
567 mchip_delay(MCHIP_HIC_CMD, 0);
568 for (j = 0; j < 100; ++j) {
569 if (mchip_delay(MCHIP_HIC_STATUS,
570 MCHIP_HIC_STATUS_IDLE))
571 return;
572 msleep(1);
573 }
574 printk(KERN_ERR "meye: need to reset HIC!\n");
575
576 mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET);
577 msleep(250);
578 }
579 printk(KERN_ERR "meye: resetting HIC hanged!\n");
580}
581
582/****************************************************************************/
583/* MCHIP frame processing functions */
584/****************************************************************************/
585
586/* get the next ready frame from the dma engine */
587static u32 mchip_get_frame(void)
588{
589 u32 v;
590
591 v = mchip_read(MCHIP_MM_FIR(meye.mchip_fnum));
592 return v;
593}
594
595/* frees the current frame from the dma engine */
596static void mchip_free_frame(void)
597{
598 mchip_set(MCHIP_MM_FIR(meye.mchip_fnum), 0);
599 meye.mchip_fnum++;
600 meye.mchip_fnum %= 4;
601}
602
603/* read one frame from the framebuffer assuming it was captured using
604 a uncompressed transfer */
605static void mchip_cont_read_frame(u32 v, u8 *buf, int size)
606{
607 int pt_id;
608
609 pt_id = (v >> 17) & 0x3FF;
610
611 ptable_copy(buf, pt_id, size, MCHIP_NB_PAGES);
612}
613
614/* read a compressed frame from the framebuffer */
615static int mchip_comp_read_frame(u32 v, u8 *buf, int size)
616{
617 int pt_start, pt_end, trailer;
618 int fsize;
619 int i;
620
621 pt_start = (v >> 19) & 0xFF;
622 pt_end = (v >> 11) & 0xFF;
623 trailer = (v >> 1) & 0x3FF;
624
625 if (pt_end < pt_start)
626 fsize = (MCHIP_NB_PAGES_MJPEG - pt_start) * PAGE_SIZE +
627 pt_end * PAGE_SIZE + trailer * 4;
628 else
629 fsize = (pt_end - pt_start) * PAGE_SIZE + trailer * 4;
630
631 if (fsize > size) {
632 printk(KERN_WARNING "meye: oversized compressed frame %d\n",
633 fsize);
634 return -1;
635 }
636
637 ptable_copy(buf, pt_start, fsize, MCHIP_NB_PAGES_MJPEG);
638
639#ifdef MEYE_JPEG_CORRECTION
640
641 /* Some mchip generated jpeg frames are incorrect. In most
642 * (all ?) of those cases, the final EOI (0xff 0xd9) marker
643 * is not present at the end of the frame.
644 *
645 * Since adding the final marker is not enough to restore
646 * the jpeg integrity, we drop the frame.
647 */
648
649 for (i = fsize - 1; i > 0 && buf[i] == 0xff; i--) ;
650
651 if (i < 2 || buf[i - 1] != 0xff || buf[i] != 0xd9)
652 return -1;
653
654#endif
655
656 return fsize;
657}
658
659/* take a picture into SDRAM */
660static void mchip_take_picture(void)
661{
662 int i;
663
664 mchip_hic_stop();
665 mchip_subsample();
666 mchip_dma_setup(meye.mchip_dmahandle);
667
668 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_CAP);
669 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
670
671 mchip_delay(MCHIP_HIC_CMD, 0);
672
673 for (i = 0; i < 100; ++i) {
674 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
675 break;
676 msleep(1);
677 }
678}
679
680/* dma a previously taken picture into a buffer */
681static void mchip_get_picture(u8 *buf, int bufsize)
682{
683 u32 v;
684 int i;
685
686 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_OUT);
687 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
688
689 mchip_delay(MCHIP_HIC_CMD, 0);
690 for (i = 0; i < 100; ++i) {
691 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
692 break;
693 msleep(1);
694 }
695 for (i = 0; i < 4; ++i) {
696 v = mchip_get_frame();
697 if (v & MCHIP_MM_FIR_RDY) {
698 mchip_cont_read_frame(v, buf, bufsize);
699 break;
700 }
701 mchip_free_frame();
702 }
703}
704
705/* start continuous dma capture */
706static void mchip_continuous_start(void)
707{
708 mchip_hic_stop();
709 mchip_subsample();
710 mchip_set_framerate();
711 mchip_dma_setup(meye.mchip_dmahandle);
712
713 meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
714
715 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_OUT);
716 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
717
718 mchip_delay(MCHIP_HIC_CMD, 0);
719}
720
721/* compress one frame into a buffer */
722static int mchip_compress_frame(u8 *buf, int bufsize)
723{
724 u32 v;
725 int len = -1, i;
726
727 mchip_vrj_setup(0x3f);
728 udelay(50);
729
730 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_COMP);
731 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
732
733 mchip_delay(MCHIP_HIC_CMD, 0);
734 for (i = 0; i < 100; ++i) {
735 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
736 break;
737 msleep(1);
738 }
739
740 for (i = 0; i < 4; ++i) {
741 v = mchip_get_frame();
742 if (v & MCHIP_MM_FIR_RDY) {
743 len = mchip_comp_read_frame(v, buf, bufsize);
744 break;
745 }
746 mchip_free_frame();
747 }
748 return len;
749}
750
751#if 0
752/* uncompress one image into a buffer */
753static int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize)
754{
755 mchip_vrj_setup(0x3f);
756 udelay(50);
757
758 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_DECOMP);
759 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
760
761 mchip_delay(MCHIP_HIC_CMD, 0);
762
763 return mchip_comp_read_frame(buf, bufsize);
764}
765#endif
766
767/* start continuous compressed capture */
768static void mchip_cont_compression_start(void)
769{
770 mchip_hic_stop();
771 mchip_vrj_setup(0x3f);
772 mchip_subsample();
773 mchip_set_framerate();
774 mchip_dma_setup(meye.mchip_dmahandle);
775
776 meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
777
778 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_COMP);
779 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
780
781 mchip_delay(MCHIP_HIC_CMD, 0);
782}
783
784/****************************************************************************/
785/* Interrupt handling */
786/****************************************************************************/
787
David Howells7d12e782006-10-05 14:55:46 +0100788static irqreturn_t meye_irq(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789{
790 u32 v;
791 int reqnr;
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300792 static int sequence;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793
794 v = mchip_read(MCHIP_MM_INTA);
795
796 if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT &&
797 meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
798 return IRQ_NONE;
799
800again:
801 v = mchip_get_frame();
802 if (!(v & MCHIP_MM_FIR_RDY))
803 return IRQ_HANDLED;
804
805 if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
806 if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
807 sizeof(int)) != sizeof(int)) {
808 mchip_free_frame();
809 return IRQ_HANDLED;
810 }
811 mchip_cont_read_frame(v, meye.grab_fbuffer + gbufsize * reqnr,
812 mchip_hsize() * mchip_vsize() * 2);
813 meye.grab_buffer[reqnr].size = mchip_hsize() * mchip_vsize() * 2;
814 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
815 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
816 meye.grab_buffer[reqnr].sequence = sequence++;
817 kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
818 wake_up_interruptible(&meye.proc_list);
819 } else {
820 int size;
821 size = mchip_comp_read_frame(v, meye.grab_temp, gbufsize);
822 if (size == -1) {
823 mchip_free_frame();
824 goto again;
825 }
826 if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
827 sizeof(int)) != sizeof(int)) {
828 mchip_free_frame();
829 goto again;
830 }
831 memcpy(meye.grab_fbuffer + gbufsize * reqnr, meye.grab_temp,
832 size);
833 meye.grab_buffer[reqnr].size = size;
834 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
835 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
836 meye.grab_buffer[reqnr].sequence = sequence++;
837 kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
838 wake_up_interruptible(&meye.proc_list);
839 }
840 mchip_free_frame();
841 goto again;
842}
843
844/****************************************************************************/
845/* video4linux integration */
846/****************************************************************************/
847
848static int meye_open(struct inode *inode, struct file *file)
849{
850 int i, err;
851
852 err = video_exclusive_open(inode, file);
853 if (err < 0)
854 return err;
855
856 mchip_hic_stop();
857
858 if (mchip_dma_alloc()) {
859 printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
860 video_exclusive_release(inode, file);
861 return -ENOBUFS;
862 }
863
864 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
865 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
866 kfifo_reset(meye.grabq);
867 kfifo_reset(meye.doneq);
868 return 0;
869}
870
871static int meye_release(struct inode *inode, struct file *file)
872{
873 mchip_hic_stop();
874 mchip_dma_free();
875 video_exclusive_release(inode, file);
876 return 0;
877}
878
879static int meye_do_ioctl(struct inode *inode, struct file *file,
880 unsigned int cmd, void *arg)
881{
882 switch (cmd) {
883
884 case VIDIOCGCAP: {
885 struct video_capability *b = arg;
886 strcpy(b->name,meye.video_dev->name);
887 b->type = VID_TYPE_CAPTURE;
888 b->channels = 1;
889 b->audios = 0;
890 b->maxwidth = 640;
891 b->maxheight = 480;
892 b->minwidth = 320;
893 b->minheight = 240;
894 break;
895 }
896
897 case VIDIOCGCHAN: {
898 struct video_channel *v = arg;
899 v->flags = 0;
900 v->tuners = 0;
901 v->type = VIDEO_TYPE_CAMERA;
902 if (v->channel != 0)
903 return -EINVAL;
904 strcpy(v->name,"Camera");
905 break;
906 }
907
908 case VIDIOCSCHAN: {
909 struct video_channel *v = arg;
910 if (v->channel != 0)
911 return -EINVAL;
912 break;
913 }
914
915 case VIDIOCGPICT: {
916 struct video_picture *p = arg;
917 *p = meye.picture;
918 break;
919 }
920
921 case VIDIOCSPICT: {
922 struct video_picture *p = arg;
923 if (p->depth != 16)
924 return -EINVAL;
audetto@tiscali.it2485eb02006-12-12 10:35:57 -0300925 if (p->palette != VIDEO_PALETTE_YUV422 && p->palette != VIDEO_PALETTE_YUYV)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 return -EINVAL;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200927 mutex_lock(&meye.lock);
malattia@linux.itcbefb762007-04-28 23:36:26 +0900928 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERABRIGHTNESS,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 p->brightness >> 10);
malattia@linux.itcbefb762007-04-28 23:36:26 +0900930 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAHUE,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 p->hue >> 10);
malattia@linux.itcbefb762007-04-28 23:36:26 +0900932 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACOLOR,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 p->colour >> 10);
malattia@linux.itcbefb762007-04-28 23:36:26 +0900934 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACONTRAST,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 p->contrast >> 10);
936 meye.picture = *p;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200937 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 break;
939 }
940
941 case VIDIOCSYNC: {
942 int *i = arg;
943 int unused;
944
945 if (*i < 0 || *i >= gbuffers)
946 return -EINVAL;
947
Ingo Molnar3593cab2006-02-07 06:49:14 -0200948 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949
950 switch (meye.grab_buffer[*i].state) {
951
952 case MEYE_BUF_UNUSED:
Ingo Molnar3593cab2006-02-07 06:49:14 -0200953 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 return -EINVAL;
955 case MEYE_BUF_USING:
956 if (file->f_flags & O_NONBLOCK) {
Ingo Molnar3593cab2006-02-07 06:49:14 -0200957 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 return -EAGAIN;
959 }
960 if (wait_event_interruptible(meye.proc_list,
961 (meye.grab_buffer[*i].state != MEYE_BUF_USING))) {
Ingo Molnar3593cab2006-02-07 06:49:14 -0200962 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 return -EINTR;
964 }
965 /* fall through */
966 case MEYE_BUF_DONE:
967 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
968 kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
969 }
Ingo Molnar3593cab2006-02-07 06:49:14 -0200970 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 break;
972 }
973
974 case VIDIOCMCAPTURE: {
975 struct video_mmap *vm = arg;
976 int restart = 0;
977
978 if (vm->frame >= gbuffers || vm->frame < 0)
979 return -EINVAL;
audetto@tiscali.it2485eb02006-12-12 10:35:57 -0300980 if (vm->format != VIDEO_PALETTE_YUV422 && vm->format != VIDEO_PALETTE_YUYV)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 return -EINVAL;
982 if (vm->height * vm->width * 2 > gbufsize)
983 return -EINVAL;
984 if (!meye.grab_fbuffer)
985 return -EINVAL;
986 if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED)
987 return -EBUSY;
988
Ingo Molnar3593cab2006-02-07 06:49:14 -0200989 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 if (vm->width == 640 && vm->height == 480) {
991 if (meye.params.subsample) {
992 meye.params.subsample = 0;
993 restart = 1;
994 }
995 } else if (vm->width == 320 && vm->height == 240) {
996 if (!meye.params.subsample) {
997 meye.params.subsample = 1;
998 restart = 1;
999 }
1000 } else {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001001 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 return -EINVAL;
1003 }
1004
1005 if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT)
1006 mchip_continuous_start();
1007 meye.grab_buffer[vm->frame].state = MEYE_BUF_USING;
1008 kfifo_put(meye.grabq, (unsigned char *)&vm->frame, sizeof(int));
Ingo Molnar3593cab2006-02-07 06:49:14 -02001009 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 break;
1011 }
1012
1013 case VIDIOCGMBUF: {
1014 struct video_mbuf *vm = arg;
1015 int i;
1016
1017 memset(vm, 0 , sizeof(*vm));
1018 vm->size = gbufsize * gbuffers;
1019 vm->frames = gbuffers;
1020 for (i = 0; i < gbuffers; i++)
1021 vm->offsets[i] = i * gbufsize;
1022 break;
1023 }
1024
1025 case MEYEIOC_G_PARAMS: {
1026 struct meye_params *p = arg;
1027 *p = meye.params;
1028 break;
1029 }
1030
1031 case MEYEIOC_S_PARAMS: {
1032 struct meye_params *jp = arg;
1033 if (jp->subsample > 1)
1034 return -EINVAL;
1035 if (jp->quality > 10)
1036 return -EINVAL;
1037 if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63)
1038 return -EINVAL;
1039 if (jp->framerate > 31)
1040 return -EINVAL;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001041 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 if (meye.params.subsample != jp->subsample ||
1043 meye.params.quality != jp->quality)
1044 mchip_hic_stop(); /* need restart */
1045 meye.params = *jp;
malattia@linux.itcbefb762007-04-28 23:36:26 +09001046 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERASHARPNESS,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 meye.params.sharpness);
malattia@linux.itcbefb762007-04-28 23:36:26 +09001048 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 meye.params.agc);
malattia@linux.itcbefb762007-04-28 23:36:26 +09001050 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 meye.params.picture);
Ingo Molnar3593cab2006-02-07 06:49:14 -02001052 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 break;
1054 }
1055
1056 case MEYEIOC_QBUF_CAPT: {
1057 int *nb = arg;
1058
1059 if (!meye.grab_fbuffer)
1060 return -EINVAL;
1061 if (*nb >= gbuffers)
1062 return -EINVAL;
1063 if (*nb < 0) {
1064 /* stop capture */
1065 mchip_hic_stop();
1066 return 0;
1067 }
1068 if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED)
1069 return -EBUSY;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001070 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
1072 mchip_cont_compression_start();
1073 meye.grab_buffer[*nb].state = MEYE_BUF_USING;
1074 kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int));
Ingo Molnar3593cab2006-02-07 06:49:14 -02001075 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 break;
1077 }
1078
1079 case MEYEIOC_SYNC: {
1080 int *i = arg;
1081 int unused;
1082
1083 if (*i < 0 || *i >= gbuffers)
1084 return -EINVAL;
1085
Ingo Molnar3593cab2006-02-07 06:49:14 -02001086 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 switch (meye.grab_buffer[*i].state) {
1088
1089 case MEYE_BUF_UNUSED:
Ingo Molnar3593cab2006-02-07 06:49:14 -02001090 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 return -EINVAL;
1092 case MEYE_BUF_USING:
1093 if (file->f_flags & O_NONBLOCK) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001094 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 return -EAGAIN;
1096 }
1097 if (wait_event_interruptible(meye.proc_list,
1098 (meye.grab_buffer[*i].state != MEYE_BUF_USING))) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001099 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 return -EINTR;
1101 }
1102 /* fall through */
1103 case MEYE_BUF_DONE:
1104 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
1105 kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
1106 }
1107 *i = meye.grab_buffer[*i].size;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001108 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 break;
1110 }
1111
1112 case MEYEIOC_STILLCAPT: {
1113
1114 if (!meye.grab_fbuffer)
1115 return -EINVAL;
1116 if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
1117 return -EBUSY;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001118 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 meye.grab_buffer[0].state = MEYE_BUF_USING;
1120 mchip_take_picture();
1121 mchip_get_picture(
1122 meye.grab_fbuffer,
1123 mchip_hsize() * mchip_vsize() * 2);
1124 meye.grab_buffer[0].state = MEYE_BUF_DONE;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001125 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 break;
1127 }
1128
1129 case MEYEIOC_STILLJCAPT: {
1130 int *len = arg;
1131
1132 if (!meye.grab_fbuffer)
1133 return -EINVAL;
1134 if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
1135 return -EBUSY;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001136 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 meye.grab_buffer[0].state = MEYE_BUF_USING;
1138 *len = -1;
1139 while (*len == -1) {
1140 mchip_take_picture();
1141 *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
1142 }
1143 meye.grab_buffer[0].state = MEYE_BUF_DONE;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001144 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 break;
1146 }
1147
1148 case VIDIOC_QUERYCAP: {
1149 struct v4l2_capability *cap = arg;
1150
1151 if (forcev4l1)
1152 return -EINVAL;
1153
1154 memset(cap, 0, sizeof(*cap));
1155 strcpy(cap->driver, "meye");
1156 strcpy(cap->card, "meye");
1157 sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev));
1158 cap->version = (MEYE_DRIVER_MAJORVERSION << 8) +
1159 MEYE_DRIVER_MINORVERSION;
1160 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1161 V4L2_CAP_STREAMING;
1162 break;
1163 }
1164
1165 case VIDIOC_ENUMINPUT: {
1166 struct v4l2_input *i = arg;
1167
1168 if (i->index != 0)
1169 return -EINVAL;
1170 memset(i, 0, sizeof(*i));
1171 i->index = 0;
1172 strcpy(i->name, "Camera");
1173 i->type = V4L2_INPUT_TYPE_CAMERA;
1174 break;
1175 }
1176
1177 case VIDIOC_G_INPUT: {
1178 int *i = arg;
1179
1180 *i = 0;
1181 break;
1182 }
1183
1184 case VIDIOC_S_INPUT: {
1185 int *i = arg;
1186
1187 if (*i != 0)
1188 return -EINVAL;
1189 break;
1190 }
1191
1192 case VIDIOC_QUERYCTRL: {
1193 struct v4l2_queryctrl *c = arg;
1194
1195 switch (c->id) {
1196
1197 case V4L2_CID_BRIGHTNESS:
1198 c->type = V4L2_CTRL_TYPE_INTEGER;
1199 strcpy(c->name, "Brightness");
1200 c->minimum = 0;
1201 c->maximum = 63;
1202 c->step = 1;
1203 c->default_value = 32;
1204 c->flags = 0;
1205 break;
1206 case V4L2_CID_HUE:
1207 c->type = V4L2_CTRL_TYPE_INTEGER;
1208 strcpy(c->name, "Hue");
1209 c->minimum = 0;
1210 c->maximum = 63;
1211 c->step = 1;
1212 c->default_value = 32;
1213 c->flags = 0;
1214 break;
1215 case V4L2_CID_CONTRAST:
1216 c->type = V4L2_CTRL_TYPE_INTEGER;
1217 strcpy(c->name, "Contrast");
1218 c->minimum = 0;
1219 c->maximum = 63;
1220 c->step = 1;
1221 c->default_value = 32;
1222 c->flags = 0;
1223 break;
1224 case V4L2_CID_SATURATION:
1225 c->type = V4L2_CTRL_TYPE_INTEGER;
1226 strcpy(c->name, "Saturation");
1227 c->minimum = 0;
1228 c->maximum = 63;
1229 c->step = 1;
1230 c->default_value = 32;
1231 c->flags = 0;
1232 break;
1233 case V4L2_CID_AGC:
1234 c->type = V4L2_CTRL_TYPE_INTEGER;
1235 strcpy(c->name, "Agc");
1236 c->minimum = 0;
1237 c->maximum = 63;
1238 c->step = 1;
1239 c->default_value = 48;
1240 c->flags = 0;
1241 break;
Brandon Philipse723ee02008-04-22 14:42:06 -03001242 case V4L2_CID_MEYE_SHARPNESS:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 case V4L2_CID_SHARPNESS:
1244 c->type = V4L2_CTRL_TYPE_INTEGER;
1245 strcpy(c->name, "Sharpness");
1246 c->minimum = 0;
1247 c->maximum = 63;
1248 c->step = 1;
1249 c->default_value = 32;
Brandon Philipse723ee02008-04-22 14:42:06 -03001250
1251 /* Continue to report legacy private SHARPNESS ctrl but
1252 * say it is disabled in preference to ctrl in the spec
1253 */
1254 c->flags = (c->id == V4L2_CID_SHARPNESS) ? 0 :
1255 V4L2_CTRL_FLAG_DISABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 break;
1257 case V4L2_CID_PICTURE:
1258 c->type = V4L2_CTRL_TYPE_INTEGER;
1259 strcpy(c->name, "Picture");
1260 c->minimum = 0;
1261 c->maximum = 63;
1262 c->step = 1;
1263 c->default_value = 0;
1264 c->flags = 0;
1265 break;
1266 case V4L2_CID_JPEGQUAL:
1267 c->type = V4L2_CTRL_TYPE_INTEGER;
1268 strcpy(c->name, "JPEG quality");
1269 c->minimum = 0;
1270 c->maximum = 10;
1271 c->step = 1;
1272 c->default_value = 8;
1273 c->flags = 0;
1274 break;
1275 case V4L2_CID_FRAMERATE:
1276 c->type = V4L2_CTRL_TYPE_INTEGER;
1277 strcpy(c->name, "Framerate");
1278 c->minimum = 0;
1279 c->maximum = 31;
1280 c->step = 1;
1281 c->default_value = 0;
1282 c->flags = 0;
1283 break;
1284 default:
1285 return -EINVAL;
1286 }
1287 break;
1288 }
1289
1290 case VIDIOC_S_CTRL: {
1291 struct v4l2_control *c = arg;
1292
Ingo Molnar3593cab2006-02-07 06:49:14 -02001293 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 switch (c->id) {
1295 case V4L2_CID_BRIGHTNESS:
malattia@linux.itcbefb762007-04-28 23:36:26 +09001296 sony_pic_camera_command(
1297 SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, c->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001298 meye.picture.brightness = c->value << 10;
1299 break;
1300 case V4L2_CID_HUE:
malattia@linux.itcbefb762007-04-28 23:36:26 +09001301 sony_pic_camera_command(
1302 SONY_PIC_COMMAND_SETCAMERAHUE, c->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303 meye.picture.hue = c->value << 10;
1304 break;
1305 case V4L2_CID_CONTRAST:
malattia@linux.itcbefb762007-04-28 23:36:26 +09001306 sony_pic_camera_command(
1307 SONY_PIC_COMMAND_SETCAMERACONTRAST, c->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 meye.picture.contrast = c->value << 10;
1309 break;
1310 case V4L2_CID_SATURATION:
malattia@linux.itcbefb762007-04-28 23:36:26 +09001311 sony_pic_camera_command(
1312 SONY_PIC_COMMAND_SETCAMERACOLOR, c->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313 meye.picture.colour = c->value << 10;
1314 break;
1315 case V4L2_CID_AGC:
malattia@linux.itcbefb762007-04-28 23:36:26 +09001316 sony_pic_camera_command(
1317 SONY_PIC_COMMAND_SETCAMERAAGC, c->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 meye.params.agc = c->value;
1319 break;
1320 case V4L2_CID_SHARPNESS:
Brandon Philipse723ee02008-04-22 14:42:06 -03001321 case V4L2_CID_MEYE_SHARPNESS:
malattia@linux.itcbefb762007-04-28 23:36:26 +09001322 sony_pic_camera_command(
1323 SONY_PIC_COMMAND_SETCAMERASHARPNESS, c->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 meye.params.sharpness = c->value;
1325 break;
1326 case V4L2_CID_PICTURE:
malattia@linux.itcbefb762007-04-28 23:36:26 +09001327 sony_pic_camera_command(
1328 SONY_PIC_COMMAND_SETCAMERAPICTURE, c->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329 meye.params.picture = c->value;
1330 break;
1331 case V4L2_CID_JPEGQUAL:
1332 meye.params.quality = c->value;
1333 break;
1334 case V4L2_CID_FRAMERATE:
1335 meye.params.framerate = c->value;
1336 break;
1337 default:
Ingo Molnar3593cab2006-02-07 06:49:14 -02001338 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 return -EINVAL;
1340 }
Ingo Molnar3593cab2006-02-07 06:49:14 -02001341 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 break;
1343 }
1344
1345 case VIDIOC_G_CTRL: {
1346 struct v4l2_control *c = arg;
1347
Ingo Molnar3593cab2006-02-07 06:49:14 -02001348 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 switch (c->id) {
1350 case V4L2_CID_BRIGHTNESS:
1351 c->value = meye.picture.brightness >> 10;
1352 break;
1353 case V4L2_CID_HUE:
1354 c->value = meye.picture.hue >> 10;
1355 break;
1356 case V4L2_CID_CONTRAST:
1357 c->value = meye.picture.contrast >> 10;
1358 break;
1359 case V4L2_CID_SATURATION:
1360 c->value = meye.picture.colour >> 10;
1361 break;
1362 case V4L2_CID_AGC:
1363 c->value = meye.params.agc;
1364 break;
1365 case V4L2_CID_SHARPNESS:
Brandon Philipse723ee02008-04-22 14:42:06 -03001366 case V4L2_CID_MEYE_SHARPNESS:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367 c->value = meye.params.sharpness;
1368 break;
1369 case V4L2_CID_PICTURE:
1370 c->value = meye.params.picture;
1371 break;
1372 case V4L2_CID_JPEGQUAL:
1373 c->value = meye.params.quality;
1374 break;
1375 case V4L2_CID_FRAMERATE:
1376 c->value = meye.params.framerate;
1377 break;
1378 default:
Ingo Molnar3593cab2006-02-07 06:49:14 -02001379 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 return -EINVAL;
1381 }
Ingo Molnar3593cab2006-02-07 06:49:14 -02001382 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 break;
1384 }
1385
1386 case VIDIOC_ENUM_FMT: {
1387 struct v4l2_fmtdesc *f = arg;
1388
1389 if (f->index > 1)
1390 return -EINVAL;
1391 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1392 return -EINVAL;
1393 if (f->index == 0) {
1394 /* standard YUV 422 capture */
1395 memset(f, 0, sizeof(*f));
1396 f->index = 0;
1397 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1398 f->flags = 0;
1399 strcpy(f->description, "YUV422");
1400 f->pixelformat = V4L2_PIX_FMT_YUYV;
1401 } else {
1402 /* compressed MJPEG capture */
1403 memset(f, 0, sizeof(*f));
1404 f->index = 1;
1405 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1406 f->flags = V4L2_FMT_FLAG_COMPRESSED;
1407 strcpy(f->description, "MJPEG");
1408 f->pixelformat = V4L2_PIX_FMT_MJPEG;
1409 }
1410 break;
1411 }
1412
1413 case VIDIOC_TRY_FMT: {
1414 struct v4l2_format *f = arg;
1415
1416 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1417 return -EINVAL;
1418 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
1419 f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
1420 return -EINVAL;
1421 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
1422 f->fmt.pix.field != V4L2_FIELD_NONE)
1423 return -EINVAL;
1424 f->fmt.pix.field = V4L2_FIELD_NONE;
1425 if (f->fmt.pix.width <= 320) {
1426 f->fmt.pix.width = 320;
1427 f->fmt.pix.height = 240;
1428 } else {
1429 f->fmt.pix.width = 640;
1430 f->fmt.pix.height = 480;
1431 }
1432 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1433 f->fmt.pix.sizeimage = f->fmt.pix.height *
1434 f->fmt.pix.bytesperline;
1435 f->fmt.pix.colorspace = 0;
1436 f->fmt.pix.priv = 0;
1437 break;
1438 }
1439
1440 case VIDIOC_G_FMT: {
1441 struct v4l2_format *f = arg;
1442
1443 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1444 return -EINVAL;
1445 memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
1446 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1447 switch (meye.mchip_mode) {
1448 case MCHIP_HIC_MODE_CONT_OUT:
1449 default:
1450 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1451 break;
1452 case MCHIP_HIC_MODE_CONT_COMP:
1453 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
1454 break;
1455 }
1456 f->fmt.pix.field = V4L2_FIELD_NONE;
1457 f->fmt.pix.width = mchip_hsize();
1458 f->fmt.pix.height = mchip_vsize();
1459 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1460 f->fmt.pix.sizeimage = f->fmt.pix.height *
1461 f->fmt.pix.bytesperline;
1462 f->fmt.pix.colorspace = 0;
1463 f->fmt.pix.priv = 0;
1464 break;
1465 }
1466
1467 case VIDIOC_S_FMT: {
1468 struct v4l2_format *f = arg;
1469
1470 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1471 return -EINVAL;
1472 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
1473 f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
1474 return -EINVAL;
1475 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
1476 f->fmt.pix.field != V4L2_FIELD_NONE)
1477 return -EINVAL;
1478 f->fmt.pix.field = V4L2_FIELD_NONE;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001479 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 if (f->fmt.pix.width <= 320) {
1481 f->fmt.pix.width = 320;
1482 f->fmt.pix.height = 240;
1483 meye.params.subsample = 1;
1484 } else {
1485 f->fmt.pix.width = 640;
1486 f->fmt.pix.height = 480;
1487 meye.params.subsample = 0;
1488 }
1489 switch (f->fmt.pix.pixelformat) {
1490 case V4L2_PIX_FMT_YUYV:
1491 meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
1492 break;
1493 case V4L2_PIX_FMT_MJPEG:
1494 meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
1495 break;
1496 }
Ingo Molnar3593cab2006-02-07 06:49:14 -02001497 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1499 f->fmt.pix.sizeimage = f->fmt.pix.height *
1500 f->fmt.pix.bytesperline;
1501 f->fmt.pix.colorspace = 0;
1502 f->fmt.pix.priv = 0;
1503
1504 break;
1505 }
1506
1507 case VIDIOC_REQBUFS: {
1508 struct v4l2_requestbuffers *req = arg;
1509 int i;
1510
1511 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1512 return -EINVAL;
1513 if (req->memory != V4L2_MEMORY_MMAP)
1514 return -EINVAL;
1515 if (meye.grab_fbuffer && req->count == gbuffers) {
1516 /* already allocated, no modifications */
1517 break;
1518 }
Ingo Molnar3593cab2006-02-07 06:49:14 -02001519 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 if (meye.grab_fbuffer) {
1521 for (i = 0; i < gbuffers; i++)
1522 if (meye.vma_use_count[i]) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001523 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 return -EINVAL;
1525 }
1526 rvfree(meye.grab_fbuffer, gbuffers * gbufsize);
1527 meye.grab_fbuffer = NULL;
1528 }
1529 gbuffers = max(2, min((int)req->count, MEYE_MAX_BUFNBRS));
1530 req->count = gbuffers;
1531 meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize);
1532 if (!meye.grab_fbuffer) {
1533 printk(KERN_ERR "meye: v4l framebuffer allocation"
1534 " failed\n");
Ingo Molnar3593cab2006-02-07 06:49:14 -02001535 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 return -ENOMEM;
1537 }
1538 for (i = 0; i < gbuffers; i++)
1539 meye.vma_use_count[i] = 0;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001540 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 break;
1542 }
1543
1544 case VIDIOC_QUERYBUF: {
1545 struct v4l2_buffer *buf = arg;
1546 int index = buf->index;
1547
1548 if (index < 0 || index >= gbuffers)
1549 return -EINVAL;
1550 memset(buf, 0, sizeof(*buf));
1551 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1552 buf->index = index;
1553 buf->bytesused = meye.grab_buffer[index].size;
1554 buf->flags = V4L2_BUF_FLAG_MAPPED;
1555 if (meye.grab_buffer[index].state == MEYE_BUF_USING)
1556 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1557 if (meye.grab_buffer[index].state == MEYE_BUF_DONE)
1558 buf->flags |= V4L2_BUF_FLAG_DONE;
1559 buf->field = V4L2_FIELD_NONE;
1560 buf->timestamp = meye.grab_buffer[index].timestamp;
1561 buf->sequence = meye.grab_buffer[index].sequence;
1562 buf->memory = V4L2_MEMORY_MMAP;
1563 buf->m.offset = index * gbufsize;
1564 buf->length = gbufsize;
1565 break;
1566 }
1567
1568 case VIDIOC_QBUF: {
1569 struct v4l2_buffer *buf = arg;
1570
1571 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1572 return -EINVAL;
1573 if (buf->memory != V4L2_MEMORY_MMAP)
1574 return -EINVAL;
1575 if (buf->index < 0 || buf->index >= gbuffers)
1576 return -EINVAL;
1577 if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)
1578 return -EINVAL;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001579 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1581 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1582 meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
1583 kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int));
Ingo Molnar3593cab2006-02-07 06:49:14 -02001584 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 break;
1586 }
1587
1588 case VIDIOC_DQBUF: {
1589 struct v4l2_buffer *buf = arg;
1590 int reqnr;
1591
1592 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1593 return -EINVAL;
1594 if (buf->memory != V4L2_MEMORY_MMAP)
1595 return -EINVAL;
1596
Ingo Molnar3593cab2006-02-07 06:49:14 -02001597 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001599 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 return -EAGAIN;
1601 }
1602 if (wait_event_interruptible(meye.proc_list,
1603 kfifo_len(meye.doneq) != 0) < 0) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001604 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 return -EINTR;
1606 }
1607 if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr,
1608 sizeof(int))) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001609 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 return -EBUSY;
1611 }
1612 if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001613 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 return -EINVAL;
1615 }
1616 buf->index = reqnr;
1617 buf->bytesused = meye.grab_buffer[reqnr].size;
1618 buf->flags = V4L2_BUF_FLAG_MAPPED;
1619 buf->field = V4L2_FIELD_NONE;
1620 buf->timestamp = meye.grab_buffer[reqnr].timestamp;
1621 buf->sequence = meye.grab_buffer[reqnr].sequence;
1622 buf->memory = V4L2_MEMORY_MMAP;
1623 buf->m.offset = reqnr * gbufsize;
1624 buf->length = gbufsize;
1625 meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001626 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 break;
1628 }
1629
1630 case VIDIOC_STREAMON: {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001631 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 switch (meye.mchip_mode) {
1633 case MCHIP_HIC_MODE_CONT_OUT:
1634 mchip_continuous_start();
1635 break;
1636 case MCHIP_HIC_MODE_CONT_COMP:
1637 mchip_cont_compression_start();
1638 break;
1639 default:
Ingo Molnar3593cab2006-02-07 06:49:14 -02001640 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 return -EINVAL;
1642 }
Ingo Molnar3593cab2006-02-07 06:49:14 -02001643 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 break;
1645 }
1646
1647 case VIDIOC_STREAMOFF: {
1648 int i;
1649
Ingo Molnar3593cab2006-02-07 06:49:14 -02001650 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 mchip_hic_stop();
1652 kfifo_reset(meye.grabq);
1653 kfifo_reset(meye.doneq);
1654 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
1655 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001656 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 break;
1658 }
1659
1660 /*
1661 * XXX what about private snapshot ioctls ?
1662 * Do they need to be converted to V4L2 ?
1663 */
1664
1665 default:
1666 return -ENOIOCTLCMD;
1667 }
1668
1669 return 0;
1670}
1671
1672static int meye_ioctl(struct inode *inode, struct file *file,
1673 unsigned int cmd, unsigned long arg)
1674{
1675 return video_usercopy(inode, file, cmd, arg, meye_do_ioctl);
1676}
1677
1678static unsigned int meye_poll(struct file *file, poll_table *wait)
1679{
1680 unsigned int res = 0;
1681
Ingo Molnar3593cab2006-02-07 06:49:14 -02001682 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 poll_wait(file, &meye.proc_list, wait);
1684 if (kfifo_len(meye.doneq))
1685 res = POLLIN | POLLRDNORM;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001686 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 return res;
1688}
1689
1690static void meye_vm_open(struct vm_area_struct *vma)
1691{
Mauro Carvalho Chehabd6144022006-05-19 13:08:09 -03001692 long idx = (long)vma->vm_private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 meye.vma_use_count[idx]++;
1694}
1695
1696static void meye_vm_close(struct vm_area_struct *vma)
1697{
Mauro Carvalho Chehabd6144022006-05-19 13:08:09 -03001698 long idx = (long)vma->vm_private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 meye.vma_use_count[idx]--;
1700}
1701
1702static struct vm_operations_struct meye_vm_ops = {
1703 .open = meye_vm_open,
1704 .close = meye_vm_close,
1705};
1706
1707static int meye_mmap(struct file *file, struct vm_area_struct *vma)
1708{
1709 unsigned long start = vma->vm_start;
1710 unsigned long size = vma->vm_end - vma->vm_start;
1711 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1712 unsigned long page, pos;
1713
Ingo Molnar3593cab2006-02-07 06:49:14 -02001714 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 if (size > gbuffers * gbufsize) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001716 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 return -EINVAL;
1718 }
1719 if (!meye.grab_fbuffer) {
1720 int i;
1721
1722 /* lazy allocation */
1723 meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize);
1724 if (!meye.grab_fbuffer) {
1725 printk(KERN_ERR "meye: v4l framebuffer allocation failed\n");
Ingo Molnar3593cab2006-02-07 06:49:14 -02001726 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 return -ENOMEM;
1728 }
1729 for (i = 0; i < gbuffers; i++)
1730 meye.vma_use_count[i] = 0;
1731 }
1732 pos = (unsigned long)meye.grab_fbuffer + offset;
1733
1734 while (size > 0) {
1735 page = vmalloc_to_pfn((void *)pos);
1736 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001737 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 return -EAGAIN;
1739 }
1740 start += PAGE_SIZE;
1741 pos += PAGE_SIZE;
1742 if (size > PAGE_SIZE)
1743 size -= PAGE_SIZE;
1744 else
1745 size = 0;
1746 }
1747
1748 vma->vm_ops = &meye_vm_ops;
1749 vma->vm_flags &= ~VM_IO; /* not I/O memory */
1750 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
1751 vma->vm_private_data = (void *) (offset / gbufsize);
1752 meye_vm_open(vma);
1753
Ingo Molnar3593cab2006-02-07 06:49:14 -02001754 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 return 0;
1756}
1757
Arjan van de Venfa027c22007-02-12 00:55:33 -08001758static const struct file_operations meye_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 .owner = THIS_MODULE,
1760 .open = meye_open,
1761 .release = meye_release,
1762 .mmap = meye_mmap,
1763 .ioctl = meye_ioctl,
Douglas Schilling Landgraf078ff792008-04-22 14:46:11 -03001764#ifdef CONFIG_COMPAT
Arnd Bergmann0d0fbf82006-01-09 15:24:57 -02001765 .compat_ioctl = v4l_compat_ioctl32,
Douglas Schilling Landgraf078ff792008-04-22 14:46:11 -03001766#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 .poll = meye_poll,
1768 .llseek = no_llseek,
1769};
1770
1771static struct video_device meye_template = {
1772 .owner = THIS_MODULE,
1773 .name = "meye",
1774 .type = VID_TYPE_CAPTURE,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 .fops = &meye_fops,
1776 .release = video_device_release,
1777 .minor = -1,
1778};
1779
1780#ifdef CONFIG_PM
Pavel Macheka2910682005-04-16 15:25:27 -07001781static int meye_suspend(struct pci_dev *pdev, pm_message_t state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782{
1783 pci_save_state(pdev);
1784 meye.pm_mchip_mode = meye.mchip_mode;
1785 mchip_hic_stop();
1786 mchip_set(MCHIP_MM_INTA, 0x0);
1787 return 0;
1788}
1789
1790static int meye_resume(struct pci_dev *pdev)
1791{
1792 pci_restore_state(pdev);
1793 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
1794
1795 mchip_delay(MCHIP_HIC_CMD, 0);
1796 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
1797 msleep(1);
1798 mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
1799 msleep(1);
1800 mchip_set(MCHIP_MM_PCI_MODE, 5);
1801 msleep(1);
1802 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
1803
1804 switch (meye.pm_mchip_mode) {
1805 case MCHIP_HIC_MODE_CONT_OUT:
1806 mchip_continuous_start();
1807 break;
1808 case MCHIP_HIC_MODE_CONT_COMP:
1809 mchip_cont_compression_start();
1810 break;
1811 }
1812 return 0;
1813}
1814#endif
1815
1816static int __devinit meye_probe(struct pci_dev *pcidev,
1817 const struct pci_device_id *ent)
1818{
1819 int ret = -EBUSY;
1820 unsigned long mchip_adr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
1822 if (meye.mchip_dev != NULL) {
1823 printk(KERN_ERR "meye: only one device allowed!\n");
1824 goto outnotdev;
1825 }
1826
1827 meye.mchip_dev = pcidev;
1828 meye.video_dev = video_device_alloc();
1829 if (!meye.video_dev) {
1830 printk(KERN_ERR "meye: video_device_alloc() failed!\n");
1831 goto outnotdev;
1832 }
1833
1834 ret = -ENOMEM;
1835 meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE);
1836 if (!meye.grab_temp) {
1837 printk(KERN_ERR "meye: grab buffer allocation failed\n");
1838 goto outvmalloc;
1839 }
1840
1841 spin_lock_init(&meye.grabq_lock);
1842 meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
1843 &meye.grabq_lock);
1844 if (IS_ERR(meye.grabq)) {
1845 printk(KERN_ERR "meye: fifo allocation failed\n");
1846 goto outkfifoalloc1;
1847 }
1848 spin_lock_init(&meye.doneq_lock);
1849 meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
1850 &meye.doneq_lock);
1851 if (IS_ERR(meye.doneq)) {
1852 printk(KERN_ERR "meye: fifo allocation failed\n");
1853 goto outkfifoalloc2;
1854 }
1855
1856 memcpy(meye.video_dev, &meye_template, sizeof(meye_template));
1857 meye.video_dev->dev = &meye.mchip_dev->dev;
1858
malattia@linux.itcbefb762007-04-28 23:36:26 +09001859 if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860 printk(KERN_ERR "meye: unable to power on the camera\n");
1861 printk(KERN_ERR "meye: did you enable the camera in "
1862 "sonypi using the module options ?\n");
1863 goto outsonypienable;
1864 }
1865
1866 ret = -EIO;
1867 if ((ret = pci_enable_device(meye.mchip_dev))) {
1868 printk(KERN_ERR "meye: pci_enable_device failed\n");
1869 goto outenabledev;
1870 }
1871
1872 mchip_adr = pci_resource_start(meye.mchip_dev,0);
1873 if (!mchip_adr) {
1874 printk(KERN_ERR "meye: mchip has no device base address\n");
1875 goto outregions;
1876 }
1877 if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0),
1878 pci_resource_len(meye.mchip_dev, 0),
1879 "meye")) {
1880 printk(KERN_ERR "meye: request_mem_region failed\n");
1881 goto outregions;
1882 }
1883 meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS);
1884 if (!meye.mchip_mmregs) {
1885 printk(KERN_ERR "meye: ioremap failed\n");
1886 goto outremap;
1887 }
1888
1889 meye.mchip_irq = pcidev->irq;
1890 if (request_irq(meye.mchip_irq, meye_irq,
Thomas Gleixner8076fe32006-07-01 19:29:37 -07001891 IRQF_DISABLED | IRQF_SHARED, "meye", meye_irq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 printk(KERN_ERR "meye: request_irq failed\n");
1893 goto outreqirq;
1894 }
1895
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8);
1897 pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64);
1898
1899 pci_set_master(meye.mchip_dev);
1900
1901 /* Ask the camera to perform a soft reset. */
1902 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
1903
1904 mchip_delay(MCHIP_HIC_CMD, 0);
1905 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
1906
1907 msleep(1);
1908 mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
1909
1910 msleep(1);
1911 mchip_set(MCHIP_MM_PCI_MODE, 5);
1912
1913 msleep(1);
1914 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
1915
1916 if (video_register_device(meye.video_dev, VFL_TYPE_GRABBER,
1917 video_nr) < 0) {
1918 printk(KERN_ERR "meye: video_register_device failed\n");
1919 goto outvideoreg;
1920 }
1921
Ingo Molnar3593cab2006-02-07 06:49:14 -02001922 mutex_init(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 init_waitqueue_head(&meye.proc_list);
1924 meye.picture.depth = 16;
1925 meye.picture.palette = VIDEO_PALETTE_YUV422;
1926 meye.picture.brightness = 32 << 10;
1927 meye.picture.hue = 32 << 10;
1928 meye.picture.colour = 32 << 10;
1929 meye.picture.contrast = 32 << 10;
1930 meye.picture.whiteness = 0;
1931 meye.params.subsample = 0;
1932 meye.params.quality = 8;
1933 meye.params.sharpness = 32;
1934 meye.params.agc = 48;
1935 meye.params.picture = 0;
1936 meye.params.framerate = 0;
1937
malattia@linux.itcbefb762007-04-28 23:36:26 +09001938 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, 32);
1939 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAHUE, 32);
1940 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACOLOR, 32);
1941 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACONTRAST, 32);
1942 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERASHARPNESS, 32);
1943 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0);
1944 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945
1946 printk(KERN_INFO "meye: Motion Eye Camera Driver v%s.\n",
1947 MEYE_DRIVER_VERSION);
1948 printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n",
Auke Kok44c10132007-06-08 15:46:36 -07001949 meye.mchip_dev->revision, mchip_adr, meye.mchip_irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950
1951 return 0;
1952
1953outvideoreg:
1954 free_irq(meye.mchip_irq, meye_irq);
1955outreqirq:
1956 iounmap(meye.mchip_mmregs);
1957outremap:
1958 release_mem_region(pci_resource_start(meye.mchip_dev, 0),
1959 pci_resource_len(meye.mchip_dev, 0));
1960outregions:
1961 pci_disable_device(meye.mchip_dev);
1962outenabledev:
malattia@linux.itcbefb762007-04-28 23:36:26 +09001963 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964outsonypienable:
1965 kfifo_free(meye.doneq);
1966outkfifoalloc2:
1967 kfifo_free(meye.grabq);
1968outkfifoalloc1:
1969 vfree(meye.grab_temp);
1970outvmalloc:
1971 video_device_release(meye.video_dev);
1972outnotdev:
1973 return ret;
1974}
1975
1976static void __devexit meye_remove(struct pci_dev *pcidev)
1977{
1978 video_unregister_device(meye.video_dev);
1979
1980 mchip_hic_stop();
1981
1982 mchip_dma_free();
1983
1984 /* disable interrupts */
1985 mchip_set(MCHIP_MM_INTA, 0x0);
1986
1987 free_irq(meye.mchip_irq, meye_irq);
1988
1989 iounmap(meye.mchip_mmregs);
1990
1991 release_mem_region(pci_resource_start(meye.mchip_dev, 0),
1992 pci_resource_len(meye.mchip_dev, 0));
1993
1994 pci_disable_device(meye.mchip_dev);
1995
malattia@linux.itcbefb762007-04-28 23:36:26 +09001996 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997
1998 kfifo_free(meye.doneq);
1999 kfifo_free(meye.grabq);
2000
2001 vfree(meye.grab_temp);
2002
2003 if (meye.grab_fbuffer) {
2004 rvfree(meye.grab_fbuffer, gbuffers*gbufsize);
2005 meye.grab_fbuffer = NULL;
2006 }
2007
2008 printk(KERN_INFO "meye: removed\n");
2009}
2010
2011static struct pci_device_id meye_pci_tbl[] = {
2012 { PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002,
2013 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
2014 { }
2015};
2016
2017MODULE_DEVICE_TABLE(pci, meye_pci_tbl);
2018
2019static struct pci_driver meye_driver = {
2020 .name = "meye",
2021 .id_table = meye_pci_tbl,
2022 .probe = meye_probe,
2023 .remove = __devexit_p(meye_remove),
2024#ifdef CONFIG_PM
2025 .suspend = meye_suspend,
2026 .resume = meye_resume,
2027#endif
2028};
2029
2030static int __init meye_init(void)
2031{
2032 gbuffers = max(2, min((int)gbuffers, MEYE_MAX_BUFNBRS));
2033 if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE)
2034 gbufsize = MEYE_MAX_BUFSIZE;
2035 gbufsize = PAGE_ALIGN(gbufsize);
Joe Perchesac9bb7f2007-11-20 09:00:35 -03002036 printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) "
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037 "for capture\n",
2038 gbuffers,
2039 gbufsize / 1024, gbuffers * gbufsize / 1024);
2040 return pci_register_driver(&meye_driver);
2041}
2042
2043static void __exit meye_exit(void)
2044{
2045 pci_unregister_driver(&meye_driver);
2046}
2047
2048module_init(meye_init);
2049module_exit(meye_exit);