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