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