blob: b421858ccf907f8fe6a9cc06c62782b11d026ec1 [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>
Alexey Dobriyand43c36d2009-10-07 17:09:06 +040031#include <linux/sched.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/init.h>
33#include <linux/videodev.h>
Mauro Carvalho Chehab5e87efa2006-06-05 10:26:32 -030034#include <media/v4l2-common.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030035#include <media/v4l2-ioctl.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include <asm/uaccess.h>
37#include <asm/io.h>
38#include <linux/delay.h>
39#include <linux/interrupt.h>
40#include <linux/vmalloc.h>
Tobias Klauserd013a062005-09-06 15:17:07 -070041#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
43#include "meye.h"
44#include <linux/meye.h>
45
46MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -030047MODULE_DESCRIPTION("v4l2 driver for the MotionEye camera");
Linus Torvalds1da177e2005-04-16 15:20:36 -070048MODULE_LICENSE("GPL");
49MODULE_VERSION(MEYE_DRIVER_VERSION);
50
Linus Torvalds1da177e2005-04-16 15:20:36 -070051/* number of grab buffers */
52static unsigned int gbuffers = 2;
53module_param(gbuffers, int, 0444);
54MODULE_PARM_DESC(gbuffers, "number of capture buffers, default is 2 (32 max)");
55
56/* size of a grab buffer */
57static unsigned int gbufsize = MEYE_MAX_BUFSIZE;
58module_param(gbufsize, int, 0444);
59MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 614400"
60 " (will be rounded up to a page multiple)");
61
62/* /dev/videoX registration number */
63static int video_nr = -1;
64module_param(video_nr, int, 0444);
65MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)");
66
67/* driver structure - only one possible */
68static struct meye meye;
69
70/****************************************************************************/
71/* Memory allocation routines (stolen from bttv-driver.c) */
72/****************************************************************************/
73static void *rvmalloc(unsigned long size)
74{
75 void *mem;
76 unsigned long adr;
77
78 size = PAGE_ALIGN(size);
79 mem = vmalloc_32(size);
80 if (mem) {
81 memset(mem, 0, size);
82 adr = (unsigned long) mem;
83 while (size > 0) {
84 SetPageReserved(vmalloc_to_page((void *)adr));
85 adr += PAGE_SIZE;
86 size -= PAGE_SIZE;
87 }
88 }
89 return mem;
90}
91
92static void rvfree(void * mem, unsigned long size)
93{
94 unsigned long adr;
95
96 if (mem) {
97 adr = (unsigned long) mem;
98 while ((long) size > 0) {
99 ClearPageReserved(vmalloc_to_page((void *)adr));
100 adr += PAGE_SIZE;
101 size -= PAGE_SIZE;
102 }
103 vfree(mem);
104 }
105}
106
107/*
108 * return a page table pointing to N pages of locked memory
109 *
110 * NOTE: The meye device expects DMA addresses on 32 bits, we build
111 * a table of 1024 entries = 4 bytes * 1024 = 4096 bytes.
112 */
113static int ptable_alloc(void)
114{
115 u32 *pt;
116 int i;
117
118 memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
119
120 /* give only 32 bit DMA addresses */
Yang Hongyang284901a92009-04-06 19:01:15 -0700121 if (dma_set_mask(&meye.mchip_dev->dev, DMA_BIT_MASK(32)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 return -1;
123
124 meye.mchip_ptable_toc = dma_alloc_coherent(&meye.mchip_dev->dev,
125 PAGE_SIZE,
126 &meye.mchip_dmahandle,
127 GFP_KERNEL);
128 if (!meye.mchip_ptable_toc) {
129 meye.mchip_dmahandle = 0;
130 return -1;
131 }
132
133 pt = meye.mchip_ptable_toc;
134 for (i = 0; i < MCHIP_NB_PAGES; i++) {
135 dma_addr_t dma;
136 meye.mchip_ptable[i] = dma_alloc_coherent(&meye.mchip_dev->dev,
137 PAGE_SIZE,
138 &dma,
139 GFP_KERNEL);
140 if (!meye.mchip_ptable[i]) {
141 int j;
142 pt = meye.mchip_ptable_toc;
143 for (j = 0; j < i; ++j) {
144 dma = (dma_addr_t) *pt;
145 dma_free_coherent(&meye.mchip_dev->dev,
146 PAGE_SIZE,
147 meye.mchip_ptable[j], dma);
148 pt++;
149 }
150 dma_free_coherent(&meye.mchip_dev->dev,
151 PAGE_SIZE,
152 meye.mchip_ptable_toc,
153 meye.mchip_dmahandle);
154 meye.mchip_ptable_toc = NULL;
155 meye.mchip_dmahandle = 0;
156 return -1;
157 }
158 *pt = (u32) dma;
159 pt++;
160 }
161 return 0;
162}
163
164static void ptable_free(void)
165{
166 u32 *pt;
167 int i;
168
169 pt = meye.mchip_ptable_toc;
170 for (i = 0; i < MCHIP_NB_PAGES; i++) {
171 dma_addr_t dma = (dma_addr_t) *pt;
172 if (meye.mchip_ptable[i])
173 dma_free_coherent(&meye.mchip_dev->dev,
174 PAGE_SIZE,
175 meye.mchip_ptable[i], dma);
176 pt++;
177 }
178
179 if (meye.mchip_ptable_toc)
180 dma_free_coherent(&meye.mchip_dev->dev,
181 PAGE_SIZE,
182 meye.mchip_ptable_toc,
183 meye.mchip_dmahandle);
184
185 memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
186 meye.mchip_ptable_toc = NULL;
187 meye.mchip_dmahandle = 0;
188}
189
190/* copy data from ptable into buf */
191static void ptable_copy(u8 *buf, int start, int size, int pt_pages)
192{
193 int i;
194
195 for (i = 0; i < (size / PAGE_SIZE) * PAGE_SIZE; i += PAGE_SIZE) {
196 memcpy(buf + i, meye.mchip_ptable[start++], PAGE_SIZE);
197 if (start >= pt_pages)
198 start = 0;
199 }
200 memcpy(buf + i, meye.mchip_ptable[start], size % PAGE_SIZE);
201}
202
203/****************************************************************************/
204/* JPEG tables at different qualities to load into the VRJ chip */
205/****************************************************************************/
206
207/* return a set of quantisation tables based on a quality from 1 to 10 */
208static u16 *jpeg_quantisation_tables(int *length, int quality)
209{
210 static u16 jpeg_tables[][70] = { {
211 0xdbff, 0x4300, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
212 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
213 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
214 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
215 0xffff, 0xffff, 0xffff,
216 0xdbff, 0x4300, 0xff01, 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, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
220 0xffff, 0xffff, 0xffff,
221 },
222 {
223 0xdbff, 0x4300, 0x5000, 0x3c37, 0x3c46, 0x5032, 0x4146, 0x5a46,
224 0x5055, 0x785f, 0x82c8, 0x6e78, 0x786e, 0xaff5, 0x91b9, 0xffc8,
225 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
226 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
227 0xffff, 0xffff, 0xffff,
228 0xdbff, 0x4300, 0x5501, 0x5a5a, 0x6978, 0xeb78, 0x8282, 0xffeb,
229 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
230 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
231 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
232 0xffff, 0xffff, 0xffff,
233 },
234 {
235 0xdbff, 0x4300, 0x2800, 0x1e1c, 0x1e23, 0x2819, 0x2123, 0x2d23,
236 0x282b, 0x3c30, 0x4164, 0x373c, 0x3c37, 0x587b, 0x495d, 0x9164,
237 0x9980, 0x8f96, 0x8c80, 0xa08a, 0xe6b4, 0xa0c3, 0xdaaa, 0x8aad,
238 0xc88c, 0xcbff, 0xeeda, 0xfff5, 0xffff, 0xc19b, 0xffff, 0xfaff,
239 0xe6ff, 0xfffd, 0xfff8,
240 0xdbff, 0x4300, 0x2b01, 0x2d2d, 0x353c, 0x763c, 0x4141, 0xf876,
241 0x8ca5, 0xf8a5, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
242 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
243 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
244 0xf8f8, 0xf8f8, 0xfff8,
245 },
246 {
247 0xdbff, 0x4300, 0x1b00, 0x1412, 0x1417, 0x1b11, 0x1617, 0x1e17,
248 0x1b1c, 0x2820, 0x2b42, 0x2528, 0x2825, 0x3a51, 0x303d, 0x6042,
249 0x6555, 0x5f64, 0x5d55, 0x6a5b, 0x9978, 0x6a81, 0x9071, 0x5b73,
250 0x855d, 0x86b5, 0x9e90, 0xaba3, 0xabad, 0x8067, 0xc9bc, 0xa6ba,
251 0x99c7, 0xaba8, 0xffa4,
252 0xdbff, 0x4300, 0x1c01, 0x1e1e, 0x2328, 0x4e28, 0x2b2b, 0xa44e,
253 0x5d6e, 0xa46e, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
254 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
255 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
256 0xa4a4, 0xa4a4, 0xffa4,
257 },
258 {
259 0xdbff, 0x4300, 0x1400, 0x0f0e, 0x0f12, 0x140d, 0x1012, 0x1712,
260 0x1415, 0x1e18, 0x2132, 0x1c1e, 0x1e1c, 0x2c3d, 0x242e, 0x4932,
261 0x4c40, 0x474b, 0x4640, 0x5045, 0x735a, 0x5062, 0x6d55, 0x4556,
262 0x6446, 0x6588, 0x776d, 0x817b, 0x8182, 0x604e, 0x978d, 0x7d8c,
263 0x7396, 0x817e, 0xff7c,
264 0xdbff, 0x4300, 0x1501, 0x1717, 0x1a1e, 0x3b1e, 0x2121, 0x7c3b,
265 0x4653, 0x7c53, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
266 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
267 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
268 0x7c7c, 0x7c7c, 0xff7c,
269 },
270 {
271 0xdbff, 0x4300, 0x1000, 0x0c0b, 0x0c0e, 0x100a, 0x0d0e, 0x120e,
272 0x1011, 0x1813, 0x1a28, 0x1618, 0x1816, 0x2331, 0x1d25, 0x3a28,
273 0x3d33, 0x393c, 0x3833, 0x4037, 0x5c48, 0x404e, 0x5744, 0x3745,
274 0x5038, 0x516d, 0x5f57, 0x6762, 0x6768, 0x4d3e, 0x7971, 0x6470,
275 0x5c78, 0x6765, 0xff63,
276 0xdbff, 0x4300, 0x1101, 0x1212, 0x1518, 0x2f18, 0x1a1a, 0x632f,
277 0x3842, 0x6342, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
278 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
279 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
280 0x6363, 0x6363, 0xff63,
281 },
282 {
283 0xdbff, 0x4300, 0x0d00, 0x0a09, 0x0a0b, 0x0d08, 0x0a0b, 0x0e0b,
284 0x0d0e, 0x130f, 0x1520, 0x1213, 0x1312, 0x1c27, 0x171e, 0x2e20,
285 0x3129, 0x2e30, 0x2d29, 0x332c, 0x4a3a, 0x333e, 0x4636, 0x2c37,
286 0x402d, 0x4157, 0x4c46, 0x524e, 0x5253, 0x3e32, 0x615a, 0x505a,
287 0x4a60, 0x5251, 0xff4f,
288 0xdbff, 0x4300, 0x0e01, 0x0e0e, 0x1113, 0x2613, 0x1515, 0x4f26,
289 0x2d35, 0x4f35, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
290 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
291 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
292 0x4f4f, 0x4f4f, 0xff4f,
293 },
294 {
295 0xdbff, 0x4300, 0x0a00, 0x0707, 0x0708, 0x0a06, 0x0808, 0x0b08,
296 0x0a0a, 0x0e0b, 0x1018, 0x0d0e, 0x0e0d, 0x151d, 0x1116, 0x2318,
297 0x251f, 0x2224, 0x221f, 0x2621, 0x372b, 0x262f, 0x3429, 0x2129,
298 0x3022, 0x3141, 0x3934, 0x3e3b, 0x3e3e, 0x2e25, 0x4944, 0x3c43,
299 0x3748, 0x3e3d, 0xff3b,
300 0xdbff, 0x4300, 0x0a01, 0x0b0b, 0x0d0e, 0x1c0e, 0x1010, 0x3b1c,
301 0x2228, 0x3b28, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
302 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
303 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
304 0x3b3b, 0x3b3b, 0xff3b,
305 },
306 {
307 0xdbff, 0x4300, 0x0600, 0x0504, 0x0506, 0x0604, 0x0506, 0x0706,
308 0x0607, 0x0a08, 0x0a10, 0x090a, 0x0a09, 0x0e14, 0x0c0f, 0x1710,
309 0x1814, 0x1718, 0x1614, 0x1a16, 0x251d, 0x1a1f, 0x231b, 0x161c,
310 0x2016, 0x202c, 0x2623, 0x2927, 0x292a, 0x1f19, 0x302d, 0x282d,
311 0x2530, 0x2928, 0xff28,
312 0xdbff, 0x4300, 0x0701, 0x0707, 0x080a, 0x130a, 0x0a0a, 0x2813,
313 0x161a, 0x281a, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
314 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
315 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
316 0x2828, 0x2828, 0xff28,
317 },
318 {
319 0xdbff, 0x4300, 0x0300, 0x0202, 0x0203, 0x0302, 0x0303, 0x0403,
320 0x0303, 0x0504, 0x0508, 0x0405, 0x0504, 0x070a, 0x0607, 0x0c08,
321 0x0c0a, 0x0b0c, 0x0b0a, 0x0d0b, 0x120e, 0x0d10, 0x110e, 0x0b0e,
322 0x100b, 0x1016, 0x1311, 0x1514, 0x1515, 0x0f0c, 0x1817, 0x1416,
323 0x1218, 0x1514, 0xff14,
324 0xdbff, 0x4300, 0x0301, 0x0404, 0x0405, 0x0905, 0x0505, 0x1409,
325 0x0b0d, 0x140d, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
326 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
327 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
328 0x1414, 0x1414, 0xff14,
329 },
330 {
331 0xdbff, 0x4300, 0x0100, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
332 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
333 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
334 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
335 0x0101, 0x0101, 0xff01,
336 0xdbff, 0x4300, 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, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
340 0x0101, 0x0101, 0xff01,
341 } };
342
343 if (quality < 0 || quality > 10) {
344 printk(KERN_WARNING
345 "meye: invalid quality level %d - using 8\n", quality);
346 quality = 8;
347 }
348
349 *length = ARRAY_SIZE(jpeg_tables[quality]);
350 return jpeg_tables[quality];
351}
352
353/* return a generic set of huffman tables */
354static u16 *jpeg_huffman_tables(int *length)
355{
356 static u16 tables[] = {
357 0xC4FF, 0xB500, 0x0010, 0x0102, 0x0303, 0x0402, 0x0503, 0x0405,
358 0x0004, 0x0100, 0x017D, 0x0302, 0x0400, 0x0511, 0x2112, 0x4131,
359 0x1306, 0x6151, 0x2207, 0x1471, 0x8132, 0xA191, 0x2308, 0xB142,
360 0x15C1, 0xD152, 0x24F0, 0x6233, 0x8272, 0x0A09, 0x1716, 0x1918,
361 0x251A, 0x2726, 0x2928, 0x342A, 0x3635, 0x3837, 0x3A39, 0x4443,
362 0x4645, 0x4847, 0x4A49, 0x5453, 0x5655, 0x5857, 0x5A59, 0x6463,
363 0x6665, 0x6867, 0x6A69, 0x7473, 0x7675, 0x7877, 0x7A79, 0x8483,
364 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 0xA29A,
365 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8,
366 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 0xD7D6,
367 0xD9D8, 0xE1DA, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xF1EA, 0xF3F2,
368 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
369 0xC4FF, 0xB500, 0x0011, 0x0102, 0x0402, 0x0304, 0x0704, 0x0405,
370 0x0004, 0x0201, 0x0077, 0x0201, 0x1103, 0x0504, 0x3121, 0x1206,
371 0x5141, 0x6107, 0x1371, 0x3222, 0x0881, 0x4214, 0xA191, 0xC1B1,
372 0x2309, 0x5233, 0x15F0, 0x7262, 0x0AD1, 0x2416, 0xE134, 0xF125,
373 0x1817, 0x1A19, 0x2726, 0x2928, 0x352A, 0x3736, 0x3938, 0x433A,
374 0x4544, 0x4746, 0x4948, 0x534A, 0x5554, 0x5756, 0x5958, 0x635A,
375 0x6564, 0x6766, 0x6968, 0x736A, 0x7574, 0x7776, 0x7978, 0x827A,
376 0x8483, 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998,
377 0xA29A, 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6,
378 0xB9B8, 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4,
379 0xD7D6, 0xD9D8, 0xE2DA, 0xE4E3, 0xE6E5, 0xE8E7, 0xEAE9, 0xF3F2,
380 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
381 0xC4FF, 0x1F00, 0x0000, 0x0501, 0x0101, 0x0101, 0x0101, 0x0000,
382 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
383 0xFF0B,
384 0xC4FF, 0x1F00, 0x0001, 0x0103, 0x0101, 0x0101, 0x0101, 0x0101,
385 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
386 0xFF0B
387 };
388
389 *length = ARRAY_SIZE(tables);
390 return tables;
391}
392
393/****************************************************************************/
394/* MCHIP low-level functions */
395/****************************************************************************/
396
397/* returns the horizontal capture size */
398static inline int mchip_hsize(void)
399{
400 return meye.params.subsample ? 320 : 640;
401}
402
403/* returns the vertical capture size */
404static inline int mchip_vsize(void)
405{
406 return meye.params.subsample ? 240 : 480;
407}
408
409/* waits for a register to be available */
410static void mchip_sync(int reg)
411{
412 u32 status;
413 int i;
414
415 if (reg == MCHIP_MM_FIFO_DATA) {
416 for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
417 status = readl(meye.mchip_mmregs +
418 MCHIP_MM_FIFO_STATUS);
419 if (!(status & MCHIP_MM_FIFO_WAIT)) {
420 printk(KERN_WARNING "meye: fifo not ready\n");
421 return;
422 }
423 if (status & MCHIP_MM_FIFO_READY)
424 return;
425 udelay(1);
426 }
427 } else if (reg > 0x80) {
428 u32 mask = (reg < 0x100) ? MCHIP_HIC_STATUS_MCC_RDY
429 : MCHIP_HIC_STATUS_VRJ_RDY;
430 for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
431 status = readl(meye.mchip_mmregs + MCHIP_HIC_STATUS);
432 if (status & mask)
433 return;
434 udelay(1);
435 }
436 } else
437 return;
438 printk(KERN_WARNING
439 "meye: mchip_sync() timeout on reg 0x%x status=0x%x\n",
440 reg, status);
441}
442
443/* sets a value into the register */
444static inline void mchip_set(int reg, u32 v)
445{
446 mchip_sync(reg);
447 writel(v, meye.mchip_mmregs + reg);
448}
449
450/* get the register value */
451static inline u32 mchip_read(int reg)
452{
453 mchip_sync(reg);
454 return readl(meye.mchip_mmregs + reg);
455}
456
457/* wait for a register to become a particular value */
458static inline int mchip_delay(u32 reg, u32 v)
459{
460 int n = 10;
461 while (--n && mchip_read(reg) != v)
462 udelay(1);
463 return n;
464}
465
466/* setup subsampling */
467static void mchip_subsample(void)
468{
469 mchip_set(MCHIP_MCC_R_SAMPLING, meye.params.subsample);
470 mchip_set(MCHIP_MCC_R_XRANGE, mchip_hsize());
471 mchip_set(MCHIP_MCC_R_YRANGE, mchip_vsize());
472 mchip_set(MCHIP_MCC_B_XRANGE, mchip_hsize());
473 mchip_set(MCHIP_MCC_B_YRANGE, mchip_vsize());
474 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
475}
476
477/* set the framerate into the mchip */
478static void mchip_set_framerate(void)
479{
480 mchip_set(MCHIP_HIC_S_RATE, meye.params.framerate);
481}
482
483/* load some huffman and quantisation tables into the VRJ chip ready
484 for JPEG compression */
485static void mchip_load_tables(void)
486{
487 int i;
488 int length;
489 u16 *tables;
490
491 tables = jpeg_huffman_tables(&length);
492 for (i = 0; i < length; i++)
493 writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
494
495 tables = jpeg_quantisation_tables(&length, meye.params.quality);
496 for (i = 0; i < length; i++)
497 writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
498}
499
500/* setup the VRJ parameters in the chip */
501static void mchip_vrj_setup(u8 mode)
502{
503 mchip_set(MCHIP_VRJ_BUS_MODE, 5);
504 mchip_set(MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL, 0x1f);
505 mchip_set(MCHIP_VRJ_PDAT_USE, 1);
506 mchip_set(MCHIP_VRJ_IRQ_FLAG, 0xa0);
507 mchip_set(MCHIP_VRJ_MODE_SPECIFY, mode);
508 mchip_set(MCHIP_VRJ_NUM_LINES, mchip_vsize());
509 mchip_set(MCHIP_VRJ_NUM_PIXELS, mchip_hsize());
510 mchip_set(MCHIP_VRJ_NUM_COMPONENTS, 0x1b);
511 mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_LO, 0xFFFF);
512 mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_HI, 0xFFFF);
513 mchip_set(MCHIP_VRJ_COMP_DATA_FORMAT, 0xC);
514 mchip_set(MCHIP_VRJ_RESTART_INTERVAL, 0);
515 mchip_set(MCHIP_VRJ_SOF1, 0x601);
516 mchip_set(MCHIP_VRJ_SOF2, 0x1502);
517 mchip_set(MCHIP_VRJ_SOF3, 0x1503);
518 mchip_set(MCHIP_VRJ_SOF4, 0x1596);
519 mchip_set(MCHIP_VRJ_SOS, 0x0ed0);
520
521 mchip_load_tables();
522}
523
524/* sets the DMA parameters into the chip */
525static void mchip_dma_setup(dma_addr_t dma_addr)
526{
527 int i;
528
529 mchip_set(MCHIP_MM_PT_ADDR, (u32)dma_addr);
530 for (i = 0; i < 4; i++)
531 mchip_set(MCHIP_MM_FIR(i), 0);
532 meye.mchip_fnum = 0;
533}
534
535/* setup for DMA transfers - also zeros the framebuffer */
536static int mchip_dma_alloc(void)
537{
538 if (!meye.mchip_dmahandle)
539 if (ptable_alloc())
540 return -1;
541 return 0;
542}
543
544/* frees the DMA buffer */
545static void mchip_dma_free(void)
546{
547 if (meye.mchip_dmahandle) {
548 mchip_dma_setup(0);
549 ptable_free();
550 }
551}
552
553/* stop any existing HIC action and wait for any dma to complete then
554 reset the dma engine */
555static void mchip_hic_stop(void)
556{
557 int i, j;
558
559 meye.mchip_mode = MCHIP_HIC_MODE_NOOP;
560 if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY))
561 return;
562 for (i = 0; i < 20; ++i) {
563 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
564 mchip_delay(MCHIP_HIC_CMD, 0);
565 for (j = 0; j < 100; ++j) {
566 if (mchip_delay(MCHIP_HIC_STATUS,
567 MCHIP_HIC_STATUS_IDLE))
568 return;
569 msleep(1);
570 }
571 printk(KERN_ERR "meye: need to reset HIC!\n");
572
573 mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET);
574 msleep(250);
575 }
576 printk(KERN_ERR "meye: resetting HIC hanged!\n");
577}
578
579/****************************************************************************/
580/* MCHIP frame processing functions */
581/****************************************************************************/
582
583/* get the next ready frame from the dma engine */
584static u32 mchip_get_frame(void)
585{
586 u32 v;
587
588 v = mchip_read(MCHIP_MM_FIR(meye.mchip_fnum));
589 return v;
590}
591
592/* frees the current frame from the dma engine */
593static void mchip_free_frame(void)
594{
595 mchip_set(MCHIP_MM_FIR(meye.mchip_fnum), 0);
596 meye.mchip_fnum++;
597 meye.mchip_fnum %= 4;
598}
599
600/* read one frame from the framebuffer assuming it was captured using
601 a uncompressed transfer */
602static void mchip_cont_read_frame(u32 v, u8 *buf, int size)
603{
604 int pt_id;
605
606 pt_id = (v >> 17) & 0x3FF;
607
608 ptable_copy(buf, pt_id, size, MCHIP_NB_PAGES);
609}
610
611/* read a compressed frame from the framebuffer */
612static int mchip_comp_read_frame(u32 v, u8 *buf, int size)
613{
614 int pt_start, pt_end, trailer;
615 int fsize;
616 int i;
617
618 pt_start = (v >> 19) & 0xFF;
619 pt_end = (v >> 11) & 0xFF;
620 trailer = (v >> 1) & 0x3FF;
621
622 if (pt_end < pt_start)
623 fsize = (MCHIP_NB_PAGES_MJPEG - pt_start) * PAGE_SIZE +
624 pt_end * PAGE_SIZE + trailer * 4;
625 else
626 fsize = (pt_end - pt_start) * PAGE_SIZE + trailer * 4;
627
628 if (fsize > size) {
629 printk(KERN_WARNING "meye: oversized compressed frame %d\n",
630 fsize);
631 return -1;
632 }
633
634 ptable_copy(buf, pt_start, fsize, MCHIP_NB_PAGES_MJPEG);
635
636#ifdef MEYE_JPEG_CORRECTION
637
638 /* Some mchip generated jpeg frames are incorrect. In most
639 * (all ?) of those cases, the final EOI (0xff 0xd9) marker
640 * is not present at the end of the frame.
641 *
642 * Since adding the final marker is not enough to restore
643 * the jpeg integrity, we drop the frame.
644 */
645
646 for (i = fsize - 1; i > 0 && buf[i] == 0xff; i--) ;
647
648 if (i < 2 || buf[i - 1] != 0xff || buf[i] != 0xd9)
649 return -1;
650
651#endif
652
653 return fsize;
654}
655
656/* take a picture into SDRAM */
657static void mchip_take_picture(void)
658{
659 int i;
660
661 mchip_hic_stop();
662 mchip_subsample();
663 mchip_dma_setup(meye.mchip_dmahandle);
664
665 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_CAP);
666 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
667
668 mchip_delay(MCHIP_HIC_CMD, 0);
669
670 for (i = 0; i < 100; ++i) {
671 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
672 break;
673 msleep(1);
674 }
675}
676
677/* dma a previously taken picture into a buffer */
678static void mchip_get_picture(u8 *buf, int bufsize)
679{
680 u32 v;
681 int i;
682
683 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_OUT);
684 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
685
686 mchip_delay(MCHIP_HIC_CMD, 0);
687 for (i = 0; i < 100; ++i) {
688 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
689 break;
690 msleep(1);
691 }
692 for (i = 0; i < 4; ++i) {
693 v = mchip_get_frame();
694 if (v & MCHIP_MM_FIR_RDY) {
695 mchip_cont_read_frame(v, buf, bufsize);
696 break;
697 }
698 mchip_free_frame();
699 }
700}
701
702/* start continuous dma capture */
703static void mchip_continuous_start(void)
704{
705 mchip_hic_stop();
706 mchip_subsample();
707 mchip_set_framerate();
708 mchip_dma_setup(meye.mchip_dmahandle);
709
710 meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
711
712 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_OUT);
713 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
714
715 mchip_delay(MCHIP_HIC_CMD, 0);
716}
717
718/* compress one frame into a buffer */
719static int mchip_compress_frame(u8 *buf, int bufsize)
720{
721 u32 v;
722 int len = -1, i;
723
724 mchip_vrj_setup(0x3f);
725 udelay(50);
726
727 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_COMP);
728 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
729
730 mchip_delay(MCHIP_HIC_CMD, 0);
731 for (i = 0; i < 100; ++i) {
732 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
733 break;
734 msleep(1);
735 }
736
737 for (i = 0; i < 4; ++i) {
738 v = mchip_get_frame();
739 if (v & MCHIP_MM_FIR_RDY) {
740 len = mchip_comp_read_frame(v, buf, bufsize);
741 break;
742 }
743 mchip_free_frame();
744 }
745 return len;
746}
747
748#if 0
749/* uncompress one image into a buffer */
750static int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize)
751{
752 mchip_vrj_setup(0x3f);
753 udelay(50);
754
755 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_DECOMP);
756 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
757
758 mchip_delay(MCHIP_HIC_CMD, 0);
759
760 return mchip_comp_read_frame(buf, bufsize);
761}
762#endif
763
764/* start continuous compressed capture */
765static void mchip_cont_compression_start(void)
766{
767 mchip_hic_stop();
768 mchip_vrj_setup(0x3f);
769 mchip_subsample();
770 mchip_set_framerate();
771 mchip_dma_setup(meye.mchip_dmahandle);
772
773 meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
774
775 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_COMP);
776 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
777
778 mchip_delay(MCHIP_HIC_CMD, 0);
779}
780
781/****************************************************************************/
782/* Interrupt handling */
783/****************************************************************************/
784
David Howells7d12e782006-10-05 14:55:46 +0100785static irqreturn_t meye_irq(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786{
787 u32 v;
788 int reqnr;
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300789 static int sequence;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790
791 v = mchip_read(MCHIP_MM_INTA);
792
793 if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT &&
794 meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
795 return IRQ_NONE;
796
797again:
798 v = mchip_get_frame();
799 if (!(v & MCHIP_MM_FIR_RDY))
800 return IRQ_HANDLED;
801
802 if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
Stefani Seibold7acd72e2009-12-21 14:37:28 -0800803 if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr,
Stefani Seiboldc1e13f22009-12-21 14:37:27 -0800804 sizeof(int), &meye.grabq_lock) != sizeof(int)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 mchip_free_frame();
806 return IRQ_HANDLED;
807 }
808 mchip_cont_read_frame(v, meye.grab_fbuffer + gbufsize * reqnr,
809 mchip_hsize() * mchip_vsize() * 2);
810 meye.grab_buffer[reqnr].size = mchip_hsize() * mchip_vsize() * 2;
811 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
812 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
813 meye.grab_buffer[reqnr].sequence = sequence++;
Stefani Seibold7acd72e2009-12-21 14:37:28 -0800814 kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr,
Stefani Seiboldc1e13f22009-12-21 14:37:27 -0800815 sizeof(int), &meye.doneq_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 wake_up_interruptible(&meye.proc_list);
817 } else {
818 int size;
819 size = mchip_comp_read_frame(v, meye.grab_temp, gbufsize);
820 if (size == -1) {
821 mchip_free_frame();
822 goto again;
823 }
Stefani Seibold7acd72e2009-12-21 14:37:28 -0800824 if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr,
Stefani Seiboldc1e13f22009-12-21 14:37:27 -0800825 sizeof(int), &meye.grabq_lock) != sizeof(int)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 mchip_free_frame();
827 goto again;
828 }
829 memcpy(meye.grab_fbuffer + gbufsize * reqnr, meye.grab_temp,
830 size);
831 meye.grab_buffer[reqnr].size = size;
832 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
833 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
834 meye.grab_buffer[reqnr].sequence = sequence++;
Stefani Seibold7acd72e2009-12-21 14:37:28 -0800835 kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr,
Stefani Seiboldc1e13f22009-12-21 14:37:27 -0800836 sizeof(int), &meye.doneq_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 wake_up_interruptible(&meye.proc_list);
838 }
839 mchip_free_frame();
840 goto again;
841}
842
843/****************************************************************************/
844/* video4linux integration */
845/****************************************************************************/
846
Hans Verkuilbec43662008-12-30 06:58:20 -0300847static int meye_open(struct file *file)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848{
Hans Verkuil7d43cd52008-08-23 05:31:47 -0300849 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850
Hans Verkuil7d43cd52008-08-23 05:31:47 -0300851 if (test_and_set_bit(0, &meye.in_use))
852 return -EBUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853
854 mchip_hic_stop();
855
856 if (mchip_dma_alloc()) {
857 printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
Hans Verkuil7d43cd52008-08-23 05:31:47 -0300858 clear_bit(0, &meye.in_use);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 return -ENOBUFS;
860 }
861
862 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
863 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
Stefani Seibold45465482009-12-21 14:37:26 -0800864 kfifo_reset(&meye.grabq);
865 kfifo_reset(&meye.doneq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 return 0;
867}
868
Hans Verkuilbec43662008-12-30 06:58:20 -0300869static int meye_release(struct file *file)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870{
871 mchip_hic_stop();
872 mchip_dma_free();
Hans Verkuil7d43cd52008-08-23 05:31:47 -0300873 clear_bit(0, &meye.in_use);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 return 0;
875}
876
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300877static int meyeioc_g_params(struct meye_params *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878{
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300879 *p = meye.params;
880 return 0;
881}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300883static int meyeioc_s_params(struct meye_params *jp)
884{
885 if (jp->subsample > 1)
886 return -EINVAL;
887
888 if (jp->quality > 10)
889 return -EINVAL;
890
891 if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63)
892 return -EINVAL;
893
894 if (jp->framerate > 31)
895 return -EINVAL;
896
897 mutex_lock(&meye.lock);
898
899 if (meye.params.subsample != jp->subsample ||
900 meye.params.quality != jp->quality)
901 mchip_hic_stop(); /* need restart */
902
903 meye.params = *jp;
904 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERASHARPNESS,
905 meye.params.sharpness);
906 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC,
907 meye.params.agc);
908 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE,
909 meye.params.picture);
910 mutex_unlock(&meye.lock);
911
912 return 0;
913}
914
915static int meyeioc_qbuf_capt(int *nb)
916{
917 if (!meye.grab_fbuffer)
918 return -EINVAL;
919
920 if (*nb >= gbuffers)
921 return -EINVAL;
922
923 if (*nb < 0) {
924 /* stop capture */
925 mchip_hic_stop();
926 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 }
928
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300929 if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED)
930 return -EBUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300932 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300934 if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
935 mchip_cont_compression_start();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300937 meye.grab_buffer[*nb].state = MEYE_BUF_USING;
Stefani Seibold7acd72e2009-12-21 14:37:28 -0800938 kfifo_in_locked(&meye.grabq, (unsigned char *)nb, sizeof(int),
Stefani Seiboldc1e13f22009-12-21 14:37:27 -0800939 &meye.grabq_lock);
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300940 mutex_unlock(&meye.lock);
941
942 return 0;
943}
944
945static int meyeioc_sync(struct file *file, void *fh, int *i)
946{
947 int unused;
948
949 if (*i < 0 || *i >= gbuffers)
950 return -EINVAL;
951
952 mutex_lock(&meye.lock);
953 switch (meye.grab_buffer[*i].state) {
954
955 case MEYE_BUF_UNUSED:
Ingo Molnar3593cab2006-02-07 06:49:14 -0200956 mutex_unlock(&meye.lock);
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300957 return -EINVAL;
958 case MEYE_BUF_USING:
959 if (file->f_flags & O_NONBLOCK) {
Ingo Molnar3593cab2006-02-07 06:49:14 -0200960 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 return -EAGAIN;
962 }
963 if (wait_event_interruptible(meye.proc_list,
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300964 (meye.grab_buffer[*i].state != MEYE_BUF_USING))) {
Ingo Molnar3593cab2006-02-07 06:49:14 -0200965 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 return -EINTR;
967 }
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300968 /* fall through */
969 case MEYE_BUF_DONE:
970 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
Stefani Seibold9842c382009-12-21 14:37:29 -0800971 if (kfifo_out_locked(&meye.doneq, (unsigned char *)&unused,
972 sizeof(int), &meye.doneq_lock) != sizeof(int))
973 break;
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -0300974 }
975 *i = meye.grab_buffer[*i].size;
976 mutex_unlock(&meye.lock);
977 return 0;
978}
979
980static int meyeioc_stillcapt(void)
981{
982 if (!meye.grab_fbuffer)
983 return -EINVAL;
984
985 if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
986 return -EBUSY;
987
988 mutex_lock(&meye.lock);
989 meye.grab_buffer[0].state = MEYE_BUF_USING;
990 mchip_take_picture();
991
992 mchip_get_picture(meye.grab_fbuffer,
993 mchip_hsize() * mchip_vsize() * 2);
994
995 meye.grab_buffer[0].state = MEYE_BUF_DONE;
996 mutex_unlock(&meye.lock);
997
998 return 0;
999}
1000
1001static int meyeioc_stilljcapt(int *len)
1002{
1003 if (!meye.grab_fbuffer)
1004 return -EINVAL;
1005
1006 if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
1007 return -EBUSY;
1008
1009 mutex_lock(&meye.lock);
1010 meye.grab_buffer[0].state = MEYE_BUF_USING;
1011 *len = -1;
1012
1013 while (*len == -1) {
1014 mchip_take_picture();
1015 *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 }
1017
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001018 meye.grab_buffer[0].state = MEYE_BUF_DONE;
1019 mutex_unlock(&meye.lock);
1020 return 0;
1021}
1022
1023static int vidioc_querycap(struct file *file, void *fh,
1024 struct v4l2_capability *cap)
1025{
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001026 strcpy(cap->driver, "meye");
1027 strcpy(cap->card, "meye");
1028 sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev));
1029
1030 cap->version = (MEYE_DRIVER_MAJORVERSION << 8) +
1031 MEYE_DRIVER_MINORVERSION;
1032
1033 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1034 V4L2_CAP_STREAMING;
1035
1036 return 0;
1037}
1038
1039static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
1040{
1041 if (i->index != 0)
1042 return -EINVAL;
1043
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001044 strcpy(i->name, "Camera");
1045 i->type = V4L2_INPUT_TYPE_CAMERA;
1046
1047 return 0;
1048}
1049
1050static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1051{
1052 *i = 0;
1053 return 0;
1054}
1055
1056static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
1057{
1058 if (i != 0)
1059 return -EINVAL;
1060
1061 return 0;
1062}
1063
1064static int vidioc_queryctrl(struct file *file, void *fh,
1065 struct v4l2_queryctrl *c)
1066{
1067 switch (c->id) {
1068
1069 case V4L2_CID_BRIGHTNESS:
1070 c->type = V4L2_CTRL_TYPE_INTEGER;
1071 strcpy(c->name, "Brightness");
1072 c->minimum = 0;
1073 c->maximum = 63;
1074 c->step = 1;
1075 c->default_value = 32;
1076 c->flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 break;
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001078 case V4L2_CID_HUE:
1079 c->type = V4L2_CTRL_TYPE_INTEGER;
1080 strcpy(c->name, "Hue");
1081 c->minimum = 0;
1082 c->maximum = 63;
1083 c->step = 1;
1084 c->default_value = 32;
1085 c->flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086 break;
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001087 case V4L2_CID_CONTRAST:
1088 c->type = V4L2_CTRL_TYPE_INTEGER;
1089 strcpy(c->name, "Contrast");
1090 c->minimum = 0;
1091 c->maximum = 63;
1092 c->step = 1;
1093 c->default_value = 32;
1094 c->flags = 0;
1095 break;
1096 case V4L2_CID_SATURATION:
1097 c->type = V4L2_CTRL_TYPE_INTEGER;
1098 strcpy(c->name, "Saturation");
1099 c->minimum = 0;
1100 c->maximum = 63;
1101 c->step = 1;
1102 c->default_value = 32;
1103 c->flags = 0;
1104 break;
1105 case V4L2_CID_AGC:
1106 c->type = V4L2_CTRL_TYPE_INTEGER;
1107 strcpy(c->name, "Agc");
1108 c->minimum = 0;
1109 c->maximum = 63;
1110 c->step = 1;
1111 c->default_value = 48;
1112 c->flags = 0;
1113 break;
1114 case V4L2_CID_MEYE_SHARPNESS:
1115 case V4L2_CID_SHARPNESS:
1116 c->type = V4L2_CTRL_TYPE_INTEGER;
1117 strcpy(c->name, "Sharpness");
1118 c->minimum = 0;
1119 c->maximum = 63;
1120 c->step = 1;
1121 c->default_value = 32;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001123 /* Continue to report legacy private SHARPNESS ctrl but
1124 * say it is disabled in preference to ctrl in the spec
1125 */
1126 c->flags = (c->id == V4L2_CID_SHARPNESS) ? 0 :
1127 V4L2_CTRL_FLAG_DISABLED;
1128 break;
1129 case V4L2_CID_PICTURE:
1130 c->type = V4L2_CTRL_TYPE_INTEGER;
1131 strcpy(c->name, "Picture");
1132 c->minimum = 0;
1133 c->maximum = 63;
1134 c->step = 1;
1135 c->default_value = 0;
1136 c->flags = 0;
1137 break;
1138 case V4L2_CID_JPEGQUAL:
1139 c->type = V4L2_CTRL_TYPE_INTEGER;
1140 strcpy(c->name, "JPEG quality");
1141 c->minimum = 0;
1142 c->maximum = 10;
1143 c->step = 1;
1144 c->default_value = 8;
1145 c->flags = 0;
1146 break;
1147 case V4L2_CID_FRAMERATE:
1148 c->type = V4L2_CTRL_TYPE_INTEGER;
1149 strcpy(c->name, "Framerate");
1150 c->minimum = 0;
1151 c->maximum = 31;
1152 c->step = 1;
1153 c->default_value = 0;
1154 c->flags = 0;
1155 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 default:
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001157 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 }
1159
1160 return 0;
1161}
1162
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001163static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164{
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001165 mutex_lock(&meye.lock);
1166 switch (c->id) {
1167 case V4L2_CID_BRIGHTNESS:
1168 sony_pic_camera_command(
1169 SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, c->value);
1170 meye.picture.brightness = c->value << 10;
1171 break;
1172 case V4L2_CID_HUE:
1173 sony_pic_camera_command(
1174 SONY_PIC_COMMAND_SETCAMERAHUE, c->value);
1175 meye.picture.hue = c->value << 10;
1176 break;
1177 case V4L2_CID_CONTRAST:
1178 sony_pic_camera_command(
1179 SONY_PIC_COMMAND_SETCAMERACONTRAST, c->value);
1180 meye.picture.contrast = c->value << 10;
1181 break;
1182 case V4L2_CID_SATURATION:
1183 sony_pic_camera_command(
1184 SONY_PIC_COMMAND_SETCAMERACOLOR, c->value);
1185 meye.picture.colour = c->value << 10;
1186 break;
1187 case V4L2_CID_AGC:
1188 sony_pic_camera_command(
1189 SONY_PIC_COMMAND_SETCAMERAAGC, c->value);
1190 meye.params.agc = c->value;
1191 break;
1192 case V4L2_CID_SHARPNESS:
1193 case V4L2_CID_MEYE_SHARPNESS:
1194 sony_pic_camera_command(
1195 SONY_PIC_COMMAND_SETCAMERASHARPNESS, c->value);
1196 meye.params.sharpness = c->value;
1197 break;
1198 case V4L2_CID_PICTURE:
1199 sony_pic_camera_command(
1200 SONY_PIC_COMMAND_SETCAMERAPICTURE, c->value);
1201 meye.params.picture = c->value;
1202 break;
1203 case V4L2_CID_JPEGQUAL:
1204 meye.params.quality = c->value;
1205 break;
1206 case V4L2_CID_FRAMERATE:
1207 meye.params.framerate = c->value;
1208 break;
1209 default:
1210 mutex_unlock(&meye.lock);
1211 return -EINVAL;
1212 }
1213 mutex_unlock(&meye.lock);
1214
1215 return 0;
1216}
1217
1218static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
1219{
1220 mutex_lock(&meye.lock);
1221 switch (c->id) {
1222 case V4L2_CID_BRIGHTNESS:
1223 c->value = meye.picture.brightness >> 10;
1224 break;
1225 case V4L2_CID_HUE:
1226 c->value = meye.picture.hue >> 10;
1227 break;
1228 case V4L2_CID_CONTRAST:
1229 c->value = meye.picture.contrast >> 10;
1230 break;
1231 case V4L2_CID_SATURATION:
1232 c->value = meye.picture.colour >> 10;
1233 break;
1234 case V4L2_CID_AGC:
1235 c->value = meye.params.agc;
1236 break;
1237 case V4L2_CID_SHARPNESS:
1238 case V4L2_CID_MEYE_SHARPNESS:
1239 c->value = meye.params.sharpness;
1240 break;
1241 case V4L2_CID_PICTURE:
1242 c->value = meye.params.picture;
1243 break;
1244 case V4L2_CID_JPEGQUAL:
1245 c->value = meye.params.quality;
1246 break;
1247 case V4L2_CID_FRAMERATE:
1248 c->value = meye.params.framerate;
1249 break;
1250 default:
1251 mutex_unlock(&meye.lock);
1252 return -EINVAL;
1253 }
1254 mutex_unlock(&meye.lock);
1255
1256 return 0;
1257}
1258
Hans Verkuil78b526a2008-05-28 12:16:41 -03001259static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001260 struct v4l2_fmtdesc *f)
1261{
1262 if (f->index > 1)
1263 return -EINVAL;
1264
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001265 if (f->index == 0) {
1266 /* standard YUV 422 capture */
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001267 f->flags = 0;
1268 strcpy(f->description, "YUV422");
1269 f->pixelformat = V4L2_PIX_FMT_YUYV;
1270 } else {
1271 /* compressed MJPEG capture */
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001272 f->flags = V4L2_FMT_FLAG_COMPRESSED;
1273 strcpy(f->description, "MJPEG");
1274 f->pixelformat = V4L2_PIX_FMT_MJPEG;
1275 }
1276
1277 return 0;
1278}
1279
Hans Verkuil78b526a2008-05-28 12:16:41 -03001280static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001281 struct v4l2_format *f)
1282{
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001283 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
1284 f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
1285 return -EINVAL;
1286
1287 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
1288 f->fmt.pix.field != V4L2_FIELD_NONE)
1289 return -EINVAL;
1290
1291 f->fmt.pix.field = V4L2_FIELD_NONE;
1292
1293 if (f->fmt.pix.width <= 320) {
1294 f->fmt.pix.width = 320;
1295 f->fmt.pix.height = 240;
1296 } else {
1297 f->fmt.pix.width = 640;
1298 f->fmt.pix.height = 480;
1299 }
1300
1301 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1302 f->fmt.pix.sizeimage = f->fmt.pix.height *
1303 f->fmt.pix.bytesperline;
1304 f->fmt.pix.colorspace = 0;
1305 f->fmt.pix.priv = 0;
1306
1307 return 0;
1308}
1309
Hans Verkuil78b526a2008-05-28 12:16:41 -03001310static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
1311 struct v4l2_format *f)
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001312{
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001313 switch (meye.mchip_mode) {
1314 case MCHIP_HIC_MODE_CONT_OUT:
1315 default:
1316 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1317 break;
1318 case MCHIP_HIC_MODE_CONT_COMP:
1319 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
1320 break;
1321 }
1322
1323 f->fmt.pix.field = V4L2_FIELD_NONE;
1324 f->fmt.pix.width = mchip_hsize();
1325 f->fmt.pix.height = mchip_vsize();
1326 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1327 f->fmt.pix.sizeimage = f->fmt.pix.height *
1328 f->fmt.pix.bytesperline;
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001329
1330 return 0;
1331}
1332
Hans Verkuil78b526a2008-05-28 12:16:41 -03001333static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
1334 struct v4l2_format *f)
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001335{
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001336 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
1337 f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
1338 return -EINVAL;
1339
1340 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
1341 f->fmt.pix.field != V4L2_FIELD_NONE)
1342 return -EINVAL;
1343
1344 f->fmt.pix.field = V4L2_FIELD_NONE;
1345 mutex_lock(&meye.lock);
1346
1347 if (f->fmt.pix.width <= 320) {
1348 f->fmt.pix.width = 320;
1349 f->fmt.pix.height = 240;
1350 meye.params.subsample = 1;
1351 } else {
1352 f->fmt.pix.width = 640;
1353 f->fmt.pix.height = 480;
1354 meye.params.subsample = 0;
1355 }
1356
1357 switch (f->fmt.pix.pixelformat) {
1358 case V4L2_PIX_FMT_YUYV:
1359 meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
1360 break;
1361 case V4L2_PIX_FMT_MJPEG:
1362 meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
1363 break;
1364 }
1365
1366 mutex_unlock(&meye.lock);
1367 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1368 f->fmt.pix.sizeimage = f->fmt.pix.height *
1369 f->fmt.pix.bytesperline;
1370 f->fmt.pix.colorspace = 0;
1371 f->fmt.pix.priv = 0;
1372
1373 return 0;
1374}
1375
1376static int vidioc_reqbufs(struct file *file, void *fh,
1377 struct v4l2_requestbuffers *req)
1378{
1379 int i;
1380
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001381 if (req->memory != V4L2_MEMORY_MMAP)
1382 return -EINVAL;
1383
1384 if (meye.grab_fbuffer && req->count == gbuffers) {
1385 /* already allocated, no modifications */
1386 return 0;
1387 }
1388
1389 mutex_lock(&meye.lock);
1390 if (meye.grab_fbuffer) {
1391 for (i = 0; i < gbuffers; i++)
1392 if (meye.vma_use_count[i]) {
1393 mutex_unlock(&meye.lock);
1394 return -EINVAL;
1395 }
1396 rvfree(meye.grab_fbuffer, gbuffers * gbufsize);
1397 meye.grab_fbuffer = NULL;
1398 }
1399
1400 gbuffers = max(2, min((int)req->count, MEYE_MAX_BUFNBRS));
1401 req->count = gbuffers;
1402 meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize);
1403
1404 if (!meye.grab_fbuffer) {
1405 printk(KERN_ERR "meye: v4l framebuffer allocation"
1406 " failed\n");
1407 mutex_unlock(&meye.lock);
1408 return -ENOMEM;
1409 }
1410
1411 for (i = 0; i < gbuffers; i++)
1412 meye.vma_use_count[i] = 0;
1413
1414 mutex_unlock(&meye.lock);
1415
1416 return 0;
1417}
1418
1419static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1420{
Trent Piepho61745232009-03-28 22:25:36 -03001421 unsigned int index = buf->index;
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001422
Trent Piepho61745232009-03-28 22:25:36 -03001423 if (index >= gbuffers)
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001424 return -EINVAL;
1425
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001426 buf->bytesused = meye.grab_buffer[index].size;
1427 buf->flags = V4L2_BUF_FLAG_MAPPED;
1428
1429 if (meye.grab_buffer[index].state == MEYE_BUF_USING)
1430 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1431
1432 if (meye.grab_buffer[index].state == MEYE_BUF_DONE)
1433 buf->flags |= V4L2_BUF_FLAG_DONE;
1434
1435 buf->field = V4L2_FIELD_NONE;
1436 buf->timestamp = meye.grab_buffer[index].timestamp;
1437 buf->sequence = meye.grab_buffer[index].sequence;
1438 buf->memory = V4L2_MEMORY_MMAP;
1439 buf->m.offset = index * gbufsize;
1440 buf->length = gbufsize;
1441
1442 return 0;
1443}
1444
1445static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1446{
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001447 if (buf->memory != V4L2_MEMORY_MMAP)
1448 return -EINVAL;
1449
Trent Piepho61745232009-03-28 22:25:36 -03001450 if (buf->index >= gbuffers)
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001451 return -EINVAL;
1452
1453 if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)
1454 return -EINVAL;
1455
1456 mutex_lock(&meye.lock);
1457 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1458 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1459 meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
Stefani Seibold7acd72e2009-12-21 14:37:28 -08001460 kfifo_in_locked(&meye.grabq, (unsigned char *)&buf->index,
Stefani Seiboldc1e13f22009-12-21 14:37:27 -08001461 sizeof(int), &meye.grabq_lock);
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001462 mutex_unlock(&meye.lock);
1463
1464 return 0;
1465}
1466
1467static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1468{
1469 int reqnr;
1470
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001471 if (buf->memory != V4L2_MEMORY_MMAP)
1472 return -EINVAL;
1473
1474 mutex_lock(&meye.lock);
1475
Stefani Seibold45465482009-12-21 14:37:26 -08001476 if (kfifo_len(&meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001477 mutex_unlock(&meye.lock);
1478 return -EAGAIN;
1479 }
1480
1481 if (wait_event_interruptible(meye.proc_list,
Stefani Seibold45465482009-12-21 14:37:26 -08001482 kfifo_len(&meye.doneq) != 0) < 0) {
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001483 mutex_unlock(&meye.lock);
1484 return -EINTR;
1485 }
1486
Stefani Seibold7acd72e2009-12-21 14:37:28 -08001487 if (!kfifo_out_locked(&meye.doneq, (unsigned char *)&reqnr,
Stefani Seiboldc1e13f22009-12-21 14:37:27 -08001488 sizeof(int), &meye.doneq_lock)) {
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001489 mutex_unlock(&meye.lock);
1490 return -EBUSY;
1491 }
1492
1493 if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) {
1494 mutex_unlock(&meye.lock);
1495 return -EINVAL;
1496 }
1497
1498 buf->index = reqnr;
1499 buf->bytesused = meye.grab_buffer[reqnr].size;
1500 buf->flags = V4L2_BUF_FLAG_MAPPED;
1501 buf->field = V4L2_FIELD_NONE;
1502 buf->timestamp = meye.grab_buffer[reqnr].timestamp;
1503 buf->sequence = meye.grab_buffer[reqnr].sequence;
1504 buf->memory = V4L2_MEMORY_MMAP;
1505 buf->m.offset = reqnr * gbufsize;
1506 buf->length = gbufsize;
1507 meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED;
1508 mutex_unlock(&meye.lock);
1509
1510 return 0;
1511}
1512
1513static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1514{
1515 mutex_lock(&meye.lock);
1516
1517 switch (meye.mchip_mode) {
1518 case MCHIP_HIC_MODE_CONT_OUT:
1519 mchip_continuous_start();
1520 break;
1521 case MCHIP_HIC_MODE_CONT_COMP:
1522 mchip_cont_compression_start();
1523 break;
1524 default:
1525 mutex_unlock(&meye.lock);
1526 return -EINVAL;
1527 }
1528
1529 mutex_unlock(&meye.lock);
1530
1531 return 0;
1532}
1533
1534static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1535{
1536 mutex_lock(&meye.lock);
1537 mchip_hic_stop();
Stefani Seibold45465482009-12-21 14:37:26 -08001538 kfifo_reset(&meye.grabq);
1539 kfifo_reset(&meye.doneq);
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001540
1541 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
1542 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
1543
1544 mutex_unlock(&meye.lock);
1545 return 0;
1546}
1547
Hans Verkuil069b7472008-12-30 07:04:34 -03001548static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001549{
1550 switch (cmd) {
1551 case MEYEIOC_G_PARAMS:
1552 return meyeioc_g_params((struct meye_params *) arg);
1553
1554 case MEYEIOC_S_PARAMS:
1555 return meyeioc_s_params((struct meye_params *) arg);
1556
1557 case MEYEIOC_QBUF_CAPT:
1558 return meyeioc_qbuf_capt((int *) arg);
1559
1560 case MEYEIOC_SYNC:
1561 return meyeioc_sync(file, fh, (int *) arg);
1562
1563 case MEYEIOC_STILLCAPT:
1564 return meyeioc_stillcapt();
1565
1566 case MEYEIOC_STILLJCAPT:
1567 return meyeioc_stilljcapt((int *) arg);
1568
1569 default:
1570 return -EINVAL;
1571 }
1572
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573}
1574
1575static unsigned int meye_poll(struct file *file, poll_table *wait)
1576{
1577 unsigned int res = 0;
1578
Ingo Molnar3593cab2006-02-07 06:49:14 -02001579 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580 poll_wait(file, &meye.proc_list, wait);
Stefani Seibold45465482009-12-21 14:37:26 -08001581 if (kfifo_len(&meye.doneq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 res = POLLIN | POLLRDNORM;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001583 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 return res;
1585}
1586
1587static void meye_vm_open(struct vm_area_struct *vma)
1588{
Mauro Carvalho Chehabd6144022006-05-19 13:08:09 -03001589 long idx = (long)vma->vm_private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 meye.vma_use_count[idx]++;
1591}
1592
1593static void meye_vm_close(struct vm_area_struct *vma)
1594{
Mauro Carvalho Chehabd6144022006-05-19 13:08:09 -03001595 long idx = (long)vma->vm_private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 meye.vma_use_count[idx]--;
1597}
1598
Alexey Dobriyanf0f37e22009-09-27 22:29:37 +04001599static const struct vm_operations_struct meye_vm_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 .open = meye_vm_open,
1601 .close = meye_vm_close,
1602};
1603
1604static int meye_mmap(struct file *file, struct vm_area_struct *vma)
1605{
1606 unsigned long start = vma->vm_start;
1607 unsigned long size = vma->vm_end - vma->vm_start;
1608 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1609 unsigned long page, pos;
1610
Ingo Molnar3593cab2006-02-07 06:49:14 -02001611 mutex_lock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 if (size > gbuffers * gbufsize) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001613 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 return -EINVAL;
1615 }
1616 if (!meye.grab_fbuffer) {
1617 int i;
1618
1619 /* lazy allocation */
1620 meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize);
1621 if (!meye.grab_fbuffer) {
1622 printk(KERN_ERR "meye: v4l framebuffer allocation failed\n");
Ingo Molnar3593cab2006-02-07 06:49:14 -02001623 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 return -ENOMEM;
1625 }
1626 for (i = 0; i < gbuffers; i++)
1627 meye.vma_use_count[i] = 0;
1628 }
1629 pos = (unsigned long)meye.grab_fbuffer + offset;
1630
1631 while (size > 0) {
1632 page = vmalloc_to_pfn((void *)pos);
1633 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
Ingo Molnar3593cab2006-02-07 06:49:14 -02001634 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635 return -EAGAIN;
1636 }
1637 start += PAGE_SIZE;
1638 pos += PAGE_SIZE;
1639 if (size > PAGE_SIZE)
1640 size -= PAGE_SIZE;
1641 else
1642 size = 0;
1643 }
1644
1645 vma->vm_ops = &meye_vm_ops;
1646 vma->vm_flags &= ~VM_IO; /* not I/O memory */
1647 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
1648 vma->vm_private_data = (void *) (offset / gbufsize);
1649 meye_vm_open(vma);
1650
Ingo Molnar3593cab2006-02-07 06:49:14 -02001651 mutex_unlock(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652 return 0;
1653}
1654
Hans Verkuilbec43662008-12-30 06:58:20 -03001655static const struct v4l2_file_operations meye_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 .owner = THIS_MODULE,
1657 .open = meye_open,
1658 .release = meye_release,
1659 .mmap = meye_mmap,
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001660 .ioctl = video_ioctl2,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 .poll = meye_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662};
1663
Hans Verkuila3998102008-07-21 02:57:38 -03001664static const struct v4l2_ioctl_ops meye_ioctl_ops = {
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001665 .vidioc_querycap = vidioc_querycap,
1666 .vidioc_enum_input = vidioc_enum_input,
1667 .vidioc_g_input = vidioc_g_input,
1668 .vidioc_s_input = vidioc_s_input,
1669 .vidioc_queryctrl = vidioc_queryctrl,
1670 .vidioc_s_ctrl = vidioc_s_ctrl,
1671 .vidioc_g_ctrl = vidioc_g_ctrl,
Hans Verkuil78b526a2008-05-28 12:16:41 -03001672 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1673 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1674 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1675 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Douglas Schilling Landgraf6ec6e0c2008-04-10 02:07:14 -03001676 .vidioc_reqbufs = vidioc_reqbufs,
1677 .vidioc_querybuf = vidioc_querybuf,
1678 .vidioc_qbuf = vidioc_qbuf,
1679 .vidioc_dqbuf = vidioc_dqbuf,
1680 .vidioc_streamon = vidioc_streamon,
1681 .vidioc_streamoff = vidioc_streamoff,
1682 .vidioc_default = vidioc_default,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683};
1684
Hans Verkuila3998102008-07-21 02:57:38 -03001685static struct video_device meye_template = {
Hans Verkuila3998102008-07-21 02:57:38 -03001686 .name = "meye",
Hans Verkuila3998102008-07-21 02:57:38 -03001687 .fops = &meye_fops,
1688 .ioctl_ops = &meye_ioctl_ops,
1689 .release = video_device_release,
Hans Verkuila3998102008-07-21 02:57:38 -03001690};
1691
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692#ifdef CONFIG_PM
Pavel Macheka2910682005-04-16 15:25:27 -07001693static int meye_suspend(struct pci_dev *pdev, pm_message_t state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694{
1695 pci_save_state(pdev);
1696 meye.pm_mchip_mode = meye.mchip_mode;
1697 mchip_hic_stop();
1698 mchip_set(MCHIP_MM_INTA, 0x0);
1699 return 0;
1700}
1701
1702static int meye_resume(struct pci_dev *pdev)
1703{
1704 pci_restore_state(pdev);
1705 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
1706
1707 mchip_delay(MCHIP_HIC_CMD, 0);
1708 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
1709 msleep(1);
1710 mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
1711 msleep(1);
1712 mchip_set(MCHIP_MM_PCI_MODE, 5);
1713 msleep(1);
1714 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
1715
1716 switch (meye.pm_mchip_mode) {
1717 case MCHIP_HIC_MODE_CONT_OUT:
1718 mchip_continuous_start();
1719 break;
1720 case MCHIP_HIC_MODE_CONT_COMP:
1721 mchip_cont_compression_start();
1722 break;
1723 }
1724 return 0;
1725}
1726#endif
1727
1728static int __devinit meye_probe(struct pci_dev *pcidev,
1729 const struct pci_device_id *ent)
1730{
1731 int ret = -EBUSY;
1732 unsigned long mchip_adr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733
1734 if (meye.mchip_dev != NULL) {
1735 printk(KERN_ERR "meye: only one device allowed!\n");
1736 goto outnotdev;
1737 }
1738
Henrik Kretzschmaref0e3c22008-08-22 17:13:05 -03001739 ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 meye.mchip_dev = pcidev;
1741 meye.video_dev = video_device_alloc();
1742 if (!meye.video_dev) {
1743 printk(KERN_ERR "meye: video_device_alloc() failed!\n");
1744 goto outnotdev;
1745 }
1746
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE);
1748 if (!meye.grab_temp) {
1749 printk(KERN_ERR "meye: grab buffer allocation failed\n");
1750 goto outvmalloc;
1751 }
1752
1753 spin_lock_init(&meye.grabq_lock);
Stefani Seiboldc1e13f22009-12-21 14:37:27 -08001754 if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS,
1755 GFP_KERNEL)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 printk(KERN_ERR "meye: fifo allocation failed\n");
1757 goto outkfifoalloc1;
1758 }
1759 spin_lock_init(&meye.doneq_lock);
Stefani Seiboldc1e13f22009-12-21 14:37:27 -08001760 if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS,
1761 GFP_KERNEL)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 printk(KERN_ERR "meye: fifo allocation failed\n");
1763 goto outkfifoalloc2;
1764 }
1765
1766 memcpy(meye.video_dev, &meye_template, sizeof(meye_template));
Hans Verkuil5e85e732008-07-20 06:31:39 -03001767 meye.video_dev->parent = &meye.mchip_dev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768
Mauro Carvalho Chehab5b5aff82008-09-03 17:11:52 -03001769 ret = -EIO;
malattia@linux.itcbefb762007-04-28 23:36:26 +09001770 if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 printk(KERN_ERR "meye: unable to power on the camera\n");
1772 printk(KERN_ERR "meye: did you enable the camera in "
1773 "sonypi using the module options ?\n");
1774 goto outsonypienable;
1775 }
1776
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 if ((ret = pci_enable_device(meye.mchip_dev))) {
1778 printk(KERN_ERR "meye: pci_enable_device failed\n");
1779 goto outenabledev;
1780 }
1781
1782 mchip_adr = pci_resource_start(meye.mchip_dev,0);
1783 if (!mchip_adr) {
1784 printk(KERN_ERR "meye: mchip has no device base address\n");
1785 goto outregions;
1786 }
1787 if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0),
1788 pci_resource_len(meye.mchip_dev, 0),
1789 "meye")) {
1790 printk(KERN_ERR "meye: request_mem_region failed\n");
1791 goto outregions;
1792 }
1793 meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS);
1794 if (!meye.mchip_mmregs) {
1795 printk(KERN_ERR "meye: ioremap failed\n");
1796 goto outremap;
1797 }
1798
1799 meye.mchip_irq = pcidev->irq;
1800 if (request_irq(meye.mchip_irq, meye_irq,
Thomas Gleixner8076fe32006-07-01 19:29:37 -07001801 IRQF_DISABLED | IRQF_SHARED, "meye", meye_irq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 printk(KERN_ERR "meye: request_irq failed\n");
1803 goto outreqirq;
1804 }
1805
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8);
1807 pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64);
1808
1809 pci_set_master(meye.mchip_dev);
1810
1811 /* Ask the camera to perform a soft reset. */
1812 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
1813
1814 mchip_delay(MCHIP_HIC_CMD, 0);
1815 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
1816
1817 msleep(1);
1818 mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
1819
1820 msleep(1);
1821 mchip_set(MCHIP_MM_PCI_MODE, 5);
1822
1823 msleep(1);
1824 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
1825
1826 if (video_register_device(meye.video_dev, VFL_TYPE_GRABBER,
1827 video_nr) < 0) {
1828 printk(KERN_ERR "meye: video_register_device failed\n");
1829 goto outvideoreg;
1830 }
1831
Ingo Molnar3593cab2006-02-07 06:49:14 -02001832 mutex_init(&meye.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 init_waitqueue_head(&meye.proc_list);
1834 meye.picture.depth = 16;
1835 meye.picture.palette = VIDEO_PALETTE_YUV422;
1836 meye.picture.brightness = 32 << 10;
1837 meye.picture.hue = 32 << 10;
1838 meye.picture.colour = 32 << 10;
1839 meye.picture.contrast = 32 << 10;
1840 meye.picture.whiteness = 0;
1841 meye.params.subsample = 0;
1842 meye.params.quality = 8;
1843 meye.params.sharpness = 32;
1844 meye.params.agc = 48;
1845 meye.params.picture = 0;
1846 meye.params.framerate = 0;
1847
malattia@linux.itcbefb762007-04-28 23:36:26 +09001848 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, 32);
1849 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAHUE, 32);
1850 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACOLOR, 32);
1851 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACONTRAST, 32);
1852 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERASHARPNESS, 32);
1853 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0);
1854 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855
1856 printk(KERN_INFO "meye: Motion Eye Camera Driver v%s.\n",
1857 MEYE_DRIVER_VERSION);
1858 printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n",
Auke Kok44c10132007-06-08 15:46:36 -07001859 meye.mchip_dev->revision, mchip_adr, meye.mchip_irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
1861 return 0;
1862
1863outvideoreg:
1864 free_irq(meye.mchip_irq, meye_irq);
1865outreqirq:
1866 iounmap(meye.mchip_mmregs);
1867outremap:
1868 release_mem_region(pci_resource_start(meye.mchip_dev, 0),
1869 pci_resource_len(meye.mchip_dev, 0));
1870outregions:
1871 pci_disable_device(meye.mchip_dev);
1872outenabledev:
malattia@linux.itcbefb762007-04-28 23:36:26 +09001873 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874outsonypienable:
Stefani Seibold45465482009-12-21 14:37:26 -08001875 kfifo_free(&meye.doneq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876outkfifoalloc2:
Stefani Seibold45465482009-12-21 14:37:26 -08001877 kfifo_free(&meye.grabq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878outkfifoalloc1:
1879 vfree(meye.grab_temp);
1880outvmalloc:
1881 video_device_release(meye.video_dev);
1882outnotdev:
1883 return ret;
1884}
1885
1886static void __devexit meye_remove(struct pci_dev *pcidev)
1887{
1888 video_unregister_device(meye.video_dev);
1889
1890 mchip_hic_stop();
1891
1892 mchip_dma_free();
1893
1894 /* disable interrupts */
1895 mchip_set(MCHIP_MM_INTA, 0x0);
1896
1897 free_irq(meye.mchip_irq, meye_irq);
1898
1899 iounmap(meye.mchip_mmregs);
1900
1901 release_mem_region(pci_resource_start(meye.mchip_dev, 0),
1902 pci_resource_len(meye.mchip_dev, 0));
1903
1904 pci_disable_device(meye.mchip_dev);
1905
malattia@linux.itcbefb762007-04-28 23:36:26 +09001906 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907
Stefani Seibold45465482009-12-21 14:37:26 -08001908 kfifo_free(&meye.doneq);
1909 kfifo_free(&meye.grabq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
1911 vfree(meye.grab_temp);
1912
1913 if (meye.grab_fbuffer) {
1914 rvfree(meye.grab_fbuffer, gbuffers*gbufsize);
1915 meye.grab_fbuffer = NULL;
1916 }
1917
1918 printk(KERN_INFO "meye: removed\n");
1919}
1920
1921static struct pci_device_id meye_pci_tbl[] = {
Joe Perches76e97412009-07-05 15:59:21 -03001922 { PCI_VDEVICE(KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002), 0 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 { }
1924};
1925
1926MODULE_DEVICE_TABLE(pci, meye_pci_tbl);
1927
1928static struct pci_driver meye_driver = {
1929 .name = "meye",
1930 .id_table = meye_pci_tbl,
1931 .probe = meye_probe,
1932 .remove = __devexit_p(meye_remove),
1933#ifdef CONFIG_PM
1934 .suspend = meye_suspend,
1935 .resume = meye_resume,
1936#endif
1937};
1938
1939static int __init meye_init(void)
1940{
1941 gbuffers = max(2, min((int)gbuffers, MEYE_MAX_BUFNBRS));
1942 if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE)
1943 gbufsize = MEYE_MAX_BUFSIZE;
1944 gbufsize = PAGE_ALIGN(gbufsize);
Joe Perchesac9bb7f2007-11-20 09:00:35 -03001945 printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 "for capture\n",
1947 gbuffers,
1948 gbufsize / 1024, gbuffers * gbufsize / 1024);
1949 return pci_register_driver(&meye_driver);
1950}
1951
1952static void __exit meye_exit(void)
1953{
1954 pci_unregister_driver(&meye_driver);
1955}
1956
1957module_init(meye_init);
1958module_exit(meye_exit);