11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Motion Eye video4linux driver for Sony Vaio PictureBook 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 696de0e252cedffad61b3cb5e05662c591898e69aJan Engelhardt * Copyright (C) 2001-2002 Alcôve <www.alcove.com> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras. 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Some parts borrowed from various video4linux drivers, especially 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bttv-driver.c and zoran.c, see original files for credits. 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (at your option) any later version. 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License for more details. 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 31d43c36dc6b357fa1806800f18aa30123c747a6d1Alexey Dobriyan#include <linux/sched.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 335a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h> 3451270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil#include <linux/videodev2.h> 355e87efa3b29c105f81fea785babafb098e4e046dMauro Carvalho Chehab#include <media/v4l2-common.h> 3651270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil#include <media/v4l2-device.h> 3735ea11ff84719b1bfab2909903a9640a86552fd1Hans Verkuil#include <media/v4l2-ioctl.h> 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/vmalloc.h> 43d013a068a5675ecd8e71f585a44e7af0798a4307Tobias Klauser#include <linux/dma-mapping.h> 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "meye.h" 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/meye.h> 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Stelian Pop <stelian@popies.net>"); 496ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling LandgrafMODULE_DESCRIPTION("v4l2 driver for the MotionEye camera"); 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_VERSION(MEYE_DRIVER_VERSION); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* number of grab buffers */ 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int gbuffers = 2; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(gbuffers, int, 0444); 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(gbuffers, "number of capture buffers, default is 2 (32 max)"); 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* size of a grab buffer */ 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int gbufsize = MEYE_MAX_BUFSIZE; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(gbufsize, int, 0444); 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 614400" 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " (will be rounded up to a page multiple)"); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* /dev/videoX registration number */ 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int video_nr = -1; 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(video_nr, int, 0444); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)"); 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* driver structure - only one possible */ 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct meye meye; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Memory allocation routines (stolen from bttv-driver.c) */ 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *rvmalloc(unsigned long size) 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *mem; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long adr; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = PAGE_ALIGN(size); 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem = vmalloc_32(size); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mem) { 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(mem, 0, size); 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adr = (unsigned long) mem; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (size > 0) { 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SetPageReserved(vmalloc_to_page((void *)adr)); 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adr += PAGE_SIZE; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size -= PAGE_SIZE; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mem; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void rvfree(void * mem, unsigned long size) 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long adr; 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mem) { 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adr = (unsigned long) mem; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((long) size > 0) { 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ClearPageReserved(vmalloc_to_page((void *)adr)); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adr += PAGE_SIZE; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size -= PAGE_SIZE; 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vfree(mem); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return a page table pointing to N pages of locked memory 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE: The meye device expects DMA addresses on 32 bits, we build 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a table of 1024 entries = 4 bytes * 1024 = 4096 bytes. 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ptable_alloc(void) 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 *pt; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable)); 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* give only 32 bit DMA addresses */ 123284901a90a9e0b812ca3f5f852cbbfb60d10249dYang Hongyang if (dma_set_mask(&meye.mchip_dev->dev, DMA_BIT_MASK(32))) 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_ptable_toc = dma_alloc_coherent(&meye.mchip_dev->dev, 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PAGE_SIZE, 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &meye.mchip_dmahandle, 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GFP_KERNEL); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!meye.mchip_ptable_toc) { 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_dmahandle = 0; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pt = meye.mchip_ptable_toc; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MCHIP_NB_PAGES; i++) { 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dma_addr_t dma; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_ptable[i] = dma_alloc_coherent(&meye.mchip_dev->dev, 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PAGE_SIZE, 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dma, 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GFP_KERNEL); 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!meye.mchip_ptable[i]) { 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int j; 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pt = meye.mchip_ptable_toc; 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (j = 0; j < i; ++j) { 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dma = (dma_addr_t) *pt; 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dma_free_coherent(&meye.mchip_dev->dev, 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PAGE_SIZE, 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_ptable[j], dma); 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pt++; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dma_free_coherent(&meye.mchip_dev->dev, 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PAGE_SIZE, 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_ptable_toc, 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_dmahandle); 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_ptable_toc = NULL; 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_dmahandle = 0; 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pt = (u32) dma; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pt++; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ptable_free(void) 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 *pt; 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pt = meye.mchip_ptable_toc; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MCHIP_NB_PAGES; i++) { 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dma_addr_t dma = (dma_addr_t) *pt; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (meye.mchip_ptable[i]) 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dma_free_coherent(&meye.mchip_dev->dev, 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PAGE_SIZE, 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_ptable[i], dma); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pt++; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (meye.mchip_ptable_toc) 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dma_free_coherent(&meye.mchip_dev->dev, 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PAGE_SIZE, 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_ptable_toc, 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_dmahandle); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable)); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_ptable_toc = NULL; 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_dmahandle = 0; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* copy data from ptable into buf */ 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ptable_copy(u8 *buf, int start, int size, int pt_pages) 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < (size / PAGE_SIZE) * PAGE_SIZE; i += PAGE_SIZE) { 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(buf + i, meye.mchip_ptable[start++], PAGE_SIZE); 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (start >= pt_pages) 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start = 0; 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(buf + i, meye.mchip_ptable[start], size % PAGE_SIZE); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* JPEG tables at different qualities to load into the VRJ chip */ 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* return a set of quantisation tables based on a quality from 1 to 10 */ 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u16 *jpeg_quantisation_tables(int *length, int quality) 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static u16 jpeg_tables[][70] = { { 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0xff01, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x5000, 0x3c37, 0x3c46, 0x5032, 0x4146, 0x5a46, 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x5055, 0x785f, 0x82c8, 0x6e78, 0x786e, 0xaff5, 0x91b9, 0xffc8, 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x5501, 0x5a5a, 0x6978, 0xeb78, 0x8282, 0xffeb, 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffff, 0xffff, 0xffff, 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x2800, 0x1e1c, 0x1e23, 0x2819, 0x2123, 0x2d23, 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x282b, 0x3c30, 0x4164, 0x373c, 0x3c37, 0x587b, 0x495d, 0x9164, 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x9980, 0x8f96, 0x8c80, 0xa08a, 0xe6b4, 0xa0c3, 0xdaaa, 0x8aad, 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xc88c, 0xcbff, 0xeeda, 0xfff5, 0xffff, 0xc19b, 0xffff, 0xfaff, 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xe6ff, 0xfffd, 0xfff8, 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x2b01, 0x2d2d, 0x353c, 0x763c, 0x4141, 0xf876, 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x8ca5, 0xf8a5, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xf8f8, 0xf8f8, 0xfff8, 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x1b00, 0x1412, 0x1417, 0x1b11, 0x1617, 0x1e17, 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1b1c, 0x2820, 0x2b42, 0x2528, 0x2825, 0x3a51, 0x303d, 0x6042, 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x6555, 0x5f64, 0x5d55, 0x6a5b, 0x9978, 0x6a81, 0x9071, 0x5b73, 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x855d, 0x86b5, 0x9e90, 0xaba3, 0xabad, 0x8067, 0xc9bc, 0xa6ba, 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x99c7, 0xaba8, 0xffa4, 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x1c01, 0x1e1e, 0x2328, 0x4e28, 0x2b2b, 0xa44e, 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x5d6e, 0xa46e, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xa4a4, 0xa4a4, 0xffa4, 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x1400, 0x0f0e, 0x0f12, 0x140d, 0x1012, 0x1712, 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1415, 0x1e18, 0x2132, 0x1c1e, 0x1e1c, 0x2c3d, 0x242e, 0x4932, 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x4c40, 0x474b, 0x4640, 0x5045, 0x735a, 0x5062, 0x6d55, 0x4556, 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x6446, 0x6588, 0x776d, 0x817b, 0x8182, 0x604e, 0x978d, 0x7d8c, 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x7396, 0x817e, 0xff7c, 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x1501, 0x1717, 0x1a1e, 0x3b1e, 0x2121, 0x7c3b, 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x4653, 0x7c53, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x7c7c, 0x7c7c, 0xff7c, 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x1000, 0x0c0b, 0x0c0e, 0x100a, 0x0d0e, 0x120e, 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1011, 0x1813, 0x1a28, 0x1618, 0x1816, 0x2331, 0x1d25, 0x3a28, 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3d33, 0x393c, 0x3833, 0x4037, 0x5c48, 0x404e, 0x5744, 0x3745, 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x5038, 0x516d, 0x5f57, 0x6762, 0x6768, 0x4d3e, 0x7971, 0x6470, 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x5c78, 0x6765, 0xff63, 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x1101, 0x1212, 0x1518, 0x2f18, 0x1a1a, 0x632f, 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3842, 0x6342, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x6363, 0x6363, 0xff63, 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x0d00, 0x0a09, 0x0a0b, 0x0d08, 0x0a0b, 0x0e0b, 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0d0e, 0x130f, 0x1520, 0x1213, 0x1312, 0x1c27, 0x171e, 0x2e20, 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3129, 0x2e30, 0x2d29, 0x332c, 0x4a3a, 0x333e, 0x4636, 0x2c37, 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x402d, 0x4157, 0x4c46, 0x524e, 0x5253, 0x3e32, 0x615a, 0x505a, 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x4a60, 0x5251, 0xff4f, 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x0e01, 0x0e0e, 0x1113, 0x2613, 0x1515, 0x4f26, 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x2d35, 0x4f35, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x4f4f, 0x4f4f, 0xff4f, 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x0a00, 0x0707, 0x0708, 0x0a06, 0x0808, 0x0b08, 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0a0a, 0x0e0b, 0x1018, 0x0d0e, 0x0e0d, 0x151d, 0x1116, 0x2318, 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x251f, 0x2224, 0x221f, 0x2621, 0x372b, 0x262f, 0x3429, 0x2129, 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3022, 0x3141, 0x3934, 0x3e3b, 0x3e3e, 0x2e25, 0x4944, 0x3c43, 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3748, 0x3e3d, 0xff3b, 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x0a01, 0x0b0b, 0x0d0e, 0x1c0e, 0x1010, 0x3b1c, 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x2228, 0x3b28, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3b3b, 0x3b3b, 0xff3b, 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x0600, 0x0504, 0x0506, 0x0604, 0x0506, 0x0706, 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0607, 0x0a08, 0x0a10, 0x090a, 0x0a09, 0x0e14, 0x0c0f, 0x1710, 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1814, 0x1718, 0x1614, 0x1a16, 0x251d, 0x1a1f, 0x231b, 0x161c, 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x2016, 0x202c, 0x2623, 0x2927, 0x292a, 0x1f19, 0x302d, 0x282d, 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x2530, 0x2928, 0xff28, 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x0701, 0x0707, 0x080a, 0x130a, 0x0a0a, 0x2813, 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x161a, 0x281a, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x2828, 0x2828, 0xff28, 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x0300, 0x0202, 0x0203, 0x0302, 0x0303, 0x0403, 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0303, 0x0504, 0x0508, 0x0405, 0x0504, 0x070a, 0x0607, 0x0c08, 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0c0a, 0x0b0c, 0x0b0a, 0x0d0b, 0x120e, 0x0d10, 0x110e, 0x0b0e, 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x100b, 0x1016, 0x1311, 0x1514, 0x1515, 0x0f0c, 0x1817, 0x1416, 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1218, 0x1514, 0xff14, 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x0301, 0x0404, 0x0405, 0x0905, 0x0505, 0x1409, 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0b0d, 0x140d, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1414, 0x1414, 0xff14, 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x0100, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0101, 0x0101, 0xff01, 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdbff, 0x4300, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0101, 0x0101, 0xff01, 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } }; 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (quality < 0 || quality > 10) { 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "meye: invalid quality level %d - using 8\n", quality); 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds quality = 8; 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *length = ARRAY_SIZE(jpeg_tables[quality]); 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return jpeg_tables[quality]; 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* return a generic set of huffman tables */ 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u16 *jpeg_huffman_tables(int *length) 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static u16 tables[] = { 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xC4FF, 0xB500, 0x0010, 0x0102, 0x0303, 0x0402, 0x0503, 0x0405, 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0004, 0x0100, 0x017D, 0x0302, 0x0400, 0x0511, 0x2112, 0x4131, 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1306, 0x6151, 0x2207, 0x1471, 0x8132, 0xA191, 0x2308, 0xB142, 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x15C1, 0xD152, 0x24F0, 0x6233, 0x8272, 0x0A09, 0x1716, 0x1918, 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x251A, 0x2726, 0x2928, 0x342A, 0x3635, 0x3837, 0x3A39, 0x4443, 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x4645, 0x4847, 0x4A49, 0x5453, 0x5655, 0x5857, 0x5A59, 0x6463, 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x6665, 0x6867, 0x6A69, 0x7473, 0x7675, 0x7877, 0x7A79, 0x8483, 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 0xA29A, 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8, 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 0xD7D6, 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xD9D8, 0xE1DA, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xF1EA, 0xF3F2, 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA, 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xC4FF, 0xB500, 0x0011, 0x0102, 0x0402, 0x0304, 0x0704, 0x0405, 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0004, 0x0201, 0x0077, 0x0201, 0x1103, 0x0504, 0x3121, 0x1206, 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x5141, 0x6107, 0x1371, 0x3222, 0x0881, 0x4214, 0xA191, 0xC1B1, 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x2309, 0x5233, 0x15F0, 0x7262, 0x0AD1, 0x2416, 0xE134, 0xF125, 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1817, 0x1A19, 0x2726, 0x2928, 0x352A, 0x3736, 0x3938, 0x433A, 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x4544, 0x4746, 0x4948, 0x534A, 0x5554, 0x5756, 0x5958, 0x635A, 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x6564, 0x6766, 0x6968, 0x736A, 0x7574, 0x7776, 0x7978, 0x827A, 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x8483, 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xA29A, 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xB9B8, 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xD7D6, 0xD9D8, 0xE2DA, 0xE4E3, 0xE6E5, 0xE8E7, 0xEAE9, 0xF3F2, 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA, 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xC4FF, 0x1F00, 0x0000, 0x0501, 0x0101, 0x0101, 0x0101, 0x0000, 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09, 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xFF0B, 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xC4FF, 0x1F00, 0x0001, 0x0103, 0x0101, 0x0101, 0x0101, 0x0101, 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09, 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xFF0B 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *length = ARRAY_SIZE(tables); 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return tables; 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* MCHIP low-level functions */ 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* returns the horizontal capture size */ 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int mchip_hsize(void) 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return meye.params.subsample ? 320 : 640; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* returns the vertical capture size */ 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int mchip_vsize(void) 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return meye.params.subsample ? 240 : 480; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* waits for a register to be available */ 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_sync(int reg) 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 status; 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (reg == MCHIP_MM_FIFO_DATA) { 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MCHIP_REG_TIMEOUT; i++) { 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = readl(meye.mchip_mmregs + 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MCHIP_MM_FIFO_STATUS); 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(status & MCHIP_MM_FIFO_WAIT)) { 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "meye: fifo not ready\n"); 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status & MCHIP_MM_FIFO_READY) 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(1); 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (reg > 0x80) { 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 mask = (reg < 0x100) ? MCHIP_HIC_STATUS_MCC_RDY 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds : MCHIP_HIC_STATUS_VRJ_RDY; 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MCHIP_REG_TIMEOUT; i++) { 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = readl(meye.mchip_mmregs + MCHIP_HIC_STATUS); 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status & mask) 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(1); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "meye: mchip_sync() timeout on reg 0x%x status=0x%x\n", 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds reg, status); 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* sets a value into the register */ 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void mchip_set(int reg, u32 v) 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_sync(reg); 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writel(v, meye.mchip_mmregs + reg); 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* get the register value */ 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u32 mchip_read(int reg) 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_sync(reg); 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return readl(meye.mchip_mmregs + reg); 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* wait for a register to become a particular value */ 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int mchip_delay(u32 reg, u32 v) 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n = 10; 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (--n && mchip_read(reg) != v) 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(1); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return n; 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* setup subsampling */ 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_subsample(void) 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MCC_R_SAMPLING, meye.params.subsample); 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MCC_R_XRANGE, mchip_hsize()); 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MCC_R_YRANGE, mchip_vsize()); 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MCC_B_XRANGE, mchip_hsize()); 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MCC_B_YRANGE, mchip_vsize()); 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE); 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* set the framerate into the mchip */ 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_set_framerate(void) 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_S_RATE, meye.params.framerate); 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* load some huffman and quantisation tables into the VRJ chip ready 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for JPEG compression */ 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_load_tables(void) 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int length; 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 *tables; 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tables = jpeg_huffman_tables(&length); 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < length; i++) 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA); 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tables = jpeg_quantisation_tables(&length, meye.params.quality); 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < length; i++) 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA); 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* setup the VRJ parameters in the chip */ 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_vrj_setup(u8 mode) 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_BUS_MODE, 5); 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL, 0x1f); 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_PDAT_USE, 1); 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_IRQ_FLAG, 0xa0); 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_MODE_SPECIFY, mode); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_NUM_LINES, mchip_vsize()); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_NUM_PIXELS, mchip_hsize()); 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_NUM_COMPONENTS, 0x1b); 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_LO, 0xFFFF); 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_HI, 0xFFFF); 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_COMP_DATA_FORMAT, 0xC); 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_RESTART_INTERVAL, 0); 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_SOF1, 0x601); 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_SOF2, 0x1502); 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_SOF3, 0x1503); 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_SOF4, 0x1596); 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_SOS, 0x0ed0); 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_load_tables(); 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* sets the DMA parameters into the chip */ 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_dma_setup(dma_addr_t dma_addr) 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MM_PT_ADDR, (u32)dma_addr); 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 4; i++) 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MM_FIR(i), 0); 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_fnum = 0; 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* setup for DMA transfers - also zeros the framebuffer */ 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mchip_dma_alloc(void) 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!meye.mchip_dmahandle) 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ptable_alloc()) 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* frees the DMA buffer */ 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_dma_free(void) 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (meye.mchip_dmahandle) { 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_dma_setup(0); 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptable_free(); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* stop any existing HIC action and wait for any dma to complete then 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds reset the dma engine */ 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_hic_stop(void) 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, j; 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_mode = MCHIP_HIC_MODE_NOOP; 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY)) 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 20; ++i) { 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP); 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_CMD, 0); 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (j = 0; j < 100; ++j) { 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mchip_delay(MCHIP_HIC_STATUS, 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MCHIP_HIC_STATUS_IDLE)) 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "meye: need to reset HIC!\n"); 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET); 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(250); 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "meye: resetting HIC hanged!\n"); 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* MCHIP frame processing functions */ 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* get the next ready frame from the dma engine */ 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u32 mchip_get_frame(void) 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 v; 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v = mchip_read(MCHIP_MM_FIR(meye.mchip_fnum)); 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return v; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* frees the current frame from the dma engine */ 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_free_frame(void) 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MM_FIR(meye.mchip_fnum), 0); 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_fnum++; 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_fnum %= 4; 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* read one frame from the framebuffer assuming it was captured using 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a uncompressed transfer */ 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_cont_read_frame(u32 v, u8 *buf, int size) 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int pt_id; 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pt_id = (v >> 17) & 0x3FF; 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptable_copy(buf, pt_id, size, MCHIP_NB_PAGES); 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* read a compressed frame from the framebuffer */ 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mchip_comp_read_frame(u32 v, u8 *buf, int size) 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int pt_start, pt_end, trailer; 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fsize; 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pt_start = (v >> 19) & 0xFF; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pt_end = (v >> 11) & 0xFF; 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds trailer = (v >> 1) & 0x3FF; 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pt_end < pt_start) 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fsize = (MCHIP_NB_PAGES_MJPEG - pt_start) * PAGE_SIZE + 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pt_end * PAGE_SIZE + trailer * 4; 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fsize = (pt_end - pt_start) * PAGE_SIZE + trailer * 4; 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fsize > size) { 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "meye: oversized compressed frame %d\n", 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fsize); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptable_copy(buf, pt_start, fsize, MCHIP_NB_PAGES_MJPEG); 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef MEYE_JPEG_CORRECTION 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Some mchip generated jpeg frames are incorrect. In most 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (all ?) of those cases, the final EOI (0xff 0xd9) marker 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is not present at the end of the frame. 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Since adding the final marker is not enough to restore 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the jpeg integrity, we drop the frame. 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = fsize - 1; i > 0 && buf[i] == 0xff; i--) ; 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i < 2 || buf[i - 1] != 0xff || buf[i] != 0xd9) 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return fsize; 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* take a picture into SDRAM */ 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_take_picture(void) 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_hic_stop(); 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_subsample(); 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_dma_setup(meye.mchip_dmahandle); 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_CAP); 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_CMD, 0); 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 100; ++i) { 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* dma a previously taken picture into a buffer */ 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_get_picture(u8 *buf, int bufsize) 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 v; 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_OUT); 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START); 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_CMD, 0); 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 100; ++i) { 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 4; ++i) { 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v = mchip_get_frame(); 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (v & MCHIP_MM_FIR_RDY) { 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_cont_read_frame(v, buf, bufsize); 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_free_frame(); 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* start continuous dma capture */ 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_continuous_start(void) 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_hic_stop(); 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_subsample(); 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set_framerate(); 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_dma_setup(meye.mchip_dmahandle); 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT; 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_OUT); 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START); 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_CMD, 0); 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* compress one frame into a buffer */ 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mchip_compress_frame(u8 *buf, int bufsize) 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 v; 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len = -1, i; 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_vrj_setup(0x3f); 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(50); 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_COMP); 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START); 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_CMD, 0); 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 100; ++i) { 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 4; ++i) { 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v = mchip_get_frame(); 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (v & MCHIP_MM_FIR_RDY) { 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = mchip_comp_read_frame(v, buf, bufsize); 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_free_frame(); 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return len; 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* uncompress one image into a buffer */ 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize) 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_vrj_setup(0x3f); 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(50); 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_DECOMP); 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START); 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_CMD, 0); 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mchip_comp_read_frame(buf, bufsize); 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* start continuous compressed capture */ 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mchip_cont_compression_start(void) 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_hic_stop(); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_vrj_setup(0x3f); 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_subsample(); 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set_framerate(); 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_dma_setup(meye.mchip_dmahandle); 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP; 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_COMP); 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START); 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_CMD, 0); 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Interrupt handling */ 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7877d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t meye_irq(int irq, void *dev_id) 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 v; 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int reqnr; 791ff699e6bd02eb1c6d02c7c2b576c2ee6caab201cDouglas Schilling Landgraf static int sequence; 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v = mchip_read(MCHIP_MM_INTA); 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT && 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP) 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_NONE; 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsagain: 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v = mchip_get_frame(); 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(v & MCHIP_MM_FIR_RDY)) 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_HANDLED; 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) { 8057acd72eb85f1c7a15e8b5eb554994949241737f1Stefani Seibold if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr, 806c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold sizeof(int), &meye.grabq_lock) != sizeof(int)) { 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_free_frame(); 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_HANDLED; 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_cont_read_frame(v, meye.grab_fbuffer + gbufsize * reqnr, 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_hsize() * mchip_vsize() * 2); 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.grab_buffer[reqnr].size = mchip_hsize() * mchip_vsize() * 2; 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.grab_buffer[reqnr].sequence = sequence++; 8167acd72eb85f1c7a15e8b5eb554994949241737f1Stefani Seibold kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr, 817c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold sizeof(int), &meye.doneq_lock); 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&meye.proc_list); 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int size; 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = mchip_comp_read_frame(v, meye.grab_temp, gbufsize); 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (size == -1) { 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_free_frame(); 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto again; 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8267acd72eb85f1c7a15e8b5eb554994949241737f1Stefani Seibold if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr, 827c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold sizeof(int), &meye.grabq_lock) != sizeof(int)) { 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_free_frame(); 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto again; 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(meye.grab_fbuffer + gbufsize * reqnr, meye.grab_temp, 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size); 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.grab_buffer[reqnr].size = size; 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.grab_buffer[reqnr].sequence = sequence++; 8377acd72eb85f1c7a15e8b5eb554994949241737f1Stefani Seibold kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr, 838c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold sizeof(int), &meye.doneq_lock); 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&meye.proc_list); 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_free_frame(); 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto again; 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* video4linux integration */ 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************/ 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 849bec43661b1dc0075b7445223ba775674133b164dHans Verkuilstatic int meye_open(struct file *file) 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8517d43cd53c851e3cf04d73108d4e7e25a1104c6f5Hans Verkuil int i; 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8537d43cd53c851e3cf04d73108d4e7e25a1104c6f5Hans Verkuil if (test_and_set_bit(0, &meye.in_use)) 8547d43cd53c851e3cf04d73108d4e7e25a1104c6f5Hans Verkuil return -EBUSY; 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_hic_stop(); 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mchip_dma_alloc()) { 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "meye: mchip framebuffer allocation failed\n"); 8607d43cd53c851e3cf04d73108d4e7e25a1104c6f5Hans Verkuil clear_bit(0, &meye.in_use); 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MEYE_MAX_BUFNBRS; i++) 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.grab_buffer[i].state = MEYE_BUF_UNUSED; 86645465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold kfifo_reset(&meye.grabq); 86745465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold kfifo_reset(&meye.doneq); 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 871bec43661b1dc0075b7445223ba775674133b164dHans Verkuilstatic int meye_release(struct file *file) 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_hic_stop(); 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_dma_free(); 8757d43cd53c851e3cf04d73108d4e7e25a1104c6f5Hans Verkuil clear_bit(0, &meye.in_use); 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8796ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int meyeioc_g_params(struct meye_params *p) 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8816ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf *p = meye.params; 8826ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 8836ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8856ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int meyeioc_s_params(struct meye_params *jp) 8866ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 8876ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (jp->subsample > 1) 8886ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8906ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (jp->quality > 10) 8916ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8936ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63) 8946ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8966ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (jp->framerate > 31) 8976ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8996ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9016ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.params.subsample != jp->subsample || 9026ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.quality != jp->quality) 9036ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mchip_hic_stop(); /* need restart */ 9046ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 9056ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params = *jp; 9066ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERASHARPNESS, 9076ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.sharpness); 9086ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 9096ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.agc); 9106ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 9116ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.picture); 9126ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9146ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 9156ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9176ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int meyeioc_qbuf_capt(int *nb) 9186ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 9196ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (!meye.grab_fbuffer) 9206ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9226ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (*nb >= gbuffers) 9236ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9256ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (*nb < 0) { 9266ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf /* stop capture */ 9276ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mchip_hic_stop(); 9286ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9316ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED) 9326ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EBUSY; 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9346ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9366ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP) 9376ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mchip_cont_compression_start(); 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9396ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_buffer[*nb].state = MEYE_BUF_USING; 9407acd72eb85f1c7a15e8b5eb554994949241737f1Stefani Seibold kfifo_in_locked(&meye.grabq, (unsigned char *)nb, sizeof(int), 941c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold &meye.grabq_lock); 9426ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9446ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 9456ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9476ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int meyeioc_sync(struct file *file, void *fh, int *i) 9486ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 9496ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf int unused; 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9516ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (*i < 0 || *i >= gbuffers) 9526ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 9536ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 9546ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 9556ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf switch (meye.grab_buffer[*i].state) { 9566ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 9576ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MEYE_BUF_UNUSED: 9583593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&meye.lock); 9596ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 9606ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MEYE_BUF_USING: 9616ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (file->f_flags & O_NONBLOCK) { 9626ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 9636ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EAGAIN; 9646ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf } 9656ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (wait_event_interruptible(meye.proc_list, 9666ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { 9676ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 9686ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINTR; 9696ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf } 9706ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf /* fall through */ 9716ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MEYE_BUF_DONE: 9726ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; 9739842c38e917636fa7dc6b88aff17a8f1fd7f0cc0Stefani Seibold if (kfifo_out_locked(&meye.doneq, (unsigned char *)&unused, 9749842c38e917636fa7dc6b88aff17a8f1fd7f0cc0Stefani Seibold sizeof(int), &meye.doneq_lock) != sizeof(int)) 9759842c38e917636fa7dc6b88aff17a8f1fd7f0cc0Stefani Seibold break; 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9776ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf *i = meye.grab_buffer[*i].size; 9786ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 9796ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 9806ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 9816ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 9826ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int meyeioc_stillcapt(void) 9836ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 9846ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (!meye.grab_fbuffer) 9856ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9876ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) 9886ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EBUSY; 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9906ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 9916ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_buffer[0].state = MEYE_BUF_USING; 9926ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mchip_take_picture(); 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9946ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mchip_get_picture(meye.grab_fbuffer, 9956ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mchip_hsize() * mchip_vsize() * 2); 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9976ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_buffer[0].state = MEYE_BUF_DONE; 9986ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 9996ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 10006ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 10016ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 10026ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 10036ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int meyeioc_stilljcapt(int *len) 10046ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 10056ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (!meye.grab_fbuffer) 10066ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 10076ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 10086ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) 10096ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EBUSY; 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10116ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 10126ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_buffer[0].state = MEYE_BUF_USING; 10136ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf *len = -1; 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10156ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf while (*len == -1) { 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_take_picture(); 10176ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize); 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10206ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_buffer[0].state = MEYE_BUF_DONE; 10216ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 10226ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 10236ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10256ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_querycap(struct file *file, void *fh, 10266ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf struct v4l2_capability *cap) 10276ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 10286ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(cap->driver, "meye"); 10296ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(cap->card, "meye"); 10306ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev)); 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10326ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf cap->version = (MEYE_DRIVER_MAJORVERSION << 8) + 10336ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf MEYE_DRIVER_MINORVERSION; 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10356ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 10366ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf V4L2_CAP_STREAMING; 10376ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 10386ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 10396ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10416ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) 10426ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 10436ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (i->index != 0) 10446ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 10456ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 10466ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(i->name, "Camera"); 10476ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf i->type = V4L2_INPUT_TYPE_CAMERA; 10486ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 10496ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 10506ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 10516ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 10526ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_g_input(struct file *file, void *fh, unsigned int *i) 10536ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 10546ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf *i = 0; 10556ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 10566ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 10576ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 10586ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_s_input(struct file *file, void *fh, unsigned int i) 10596ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 10606ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (i != 0) 10616ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10636ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 10646ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 10656ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 10666ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_queryctrl(struct file *file, void *fh, 10676ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf struct v4l2_queryctrl *c) 10686ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 10696ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf switch (c->id) { 10706ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 10716ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_BRIGHTNESS: 10726ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->type = V4L2_CTRL_TYPE_INTEGER; 10736ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(c->name, "Brightness"); 10746ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->minimum = 0; 10756ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->maximum = 63; 10766ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->step = 1; 10776ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->default_value = 32; 10786ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->flags = 0; 10796ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 10806ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_HUE: 10816ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->type = V4L2_CTRL_TYPE_INTEGER; 10826ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(c->name, "Hue"); 10836ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->minimum = 0; 10846ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->maximum = 63; 10856ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->step = 1; 10866ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->default_value = 32; 10876ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->flags = 0; 10886ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 10896ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_CONTRAST: 10906ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->type = V4L2_CTRL_TYPE_INTEGER; 10916ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(c->name, "Contrast"); 10926ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->minimum = 0; 10936ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->maximum = 63; 10946ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->step = 1; 10956ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->default_value = 32; 10966ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->flags = 0; 10976ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 10986ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_SATURATION: 10996ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->type = V4L2_CTRL_TYPE_INTEGER; 11006ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(c->name, "Saturation"); 11016ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->minimum = 0; 11026ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->maximum = 63; 11036ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->step = 1; 11046ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->default_value = 32; 11056ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->flags = 0; 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11076ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_AGC: 11086ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->type = V4L2_CTRL_TYPE_INTEGER; 11096ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(c->name, "Agc"); 11106ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->minimum = 0; 11116ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->maximum = 63; 11126ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->step = 1; 11136ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->default_value = 48; 11146ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->flags = 0; 11156ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 11166ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_MEYE_SHARPNESS: 11176ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_SHARPNESS: 11186ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->type = V4L2_CTRL_TYPE_INTEGER; 11196ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(c->name, "Sharpness"); 11206ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->minimum = 0; 11216ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->maximum = 63; 11226ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->step = 1; 11236ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->default_value = 32; 11246ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 11256ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf /* Continue to report legacy private SHARPNESS ctrl but 11266ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf * say it is disabled in preference to ctrl in the spec 11276ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf */ 11286ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->flags = (c->id == V4L2_CID_SHARPNESS) ? 0 : 11296ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf V4L2_CTRL_FLAG_DISABLED; 11306ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 11316ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_PICTURE: 11326ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->type = V4L2_CTRL_TYPE_INTEGER; 11336ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(c->name, "Picture"); 11346ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->minimum = 0; 11356ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->maximum = 63; 11366ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->step = 1; 11376ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->default_value = 0; 11386ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->flags = 0; 11396ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 11406ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_JPEGQUAL: 11416ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->type = V4L2_CTRL_TYPE_INTEGER; 11426ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(c->name, "JPEG quality"); 11436ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->minimum = 0; 11446ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->maximum = 10; 11456ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->step = 1; 11466ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->default_value = 8; 11476ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->flags = 0; 11486ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 11496ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_FRAMERATE: 11506ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->type = V4L2_CTRL_TYPE_INTEGER; 11516ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(c->name, "Framerate"); 11526ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->minimum = 0; 11536ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->maximum = 31; 11546ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->step = 1; 11556ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->default_value = 0; 11566ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->flags = 0; 11576ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 11586ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf default: 11596ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11626ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 11636ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11656ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) 11666ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 11676ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 11686ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf switch (c->id) { 11696ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_BRIGHTNESS: 11706ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sony_pic_camera_command( 11716ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, c->value); 117251270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil meye.brightness = c->value << 10; 11736ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 11746ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_HUE: 11756ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sony_pic_camera_command( 11766ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf SONY_PIC_COMMAND_SETCAMERAHUE, c->value); 117751270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil meye.hue = c->value << 10; 11786ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 11796ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_CONTRAST: 11806ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sony_pic_camera_command( 11816ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf SONY_PIC_COMMAND_SETCAMERACONTRAST, c->value); 118251270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil meye.contrast = c->value << 10; 11836ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 11846ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_SATURATION: 11856ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sony_pic_camera_command( 11866ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf SONY_PIC_COMMAND_SETCAMERACOLOR, c->value); 118751270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil meye.colour = c->value << 10; 11886ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 11896ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_AGC: 11906ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sony_pic_camera_command( 11916ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf SONY_PIC_COMMAND_SETCAMERAAGC, c->value); 11926ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.agc = c->value; 11936ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 11946ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_SHARPNESS: 11956ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_MEYE_SHARPNESS: 11966ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sony_pic_camera_command( 11976ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf SONY_PIC_COMMAND_SETCAMERASHARPNESS, c->value); 11986ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.sharpness = c->value; 11996ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12006ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_PICTURE: 12016ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf sony_pic_camera_command( 12026ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf SONY_PIC_COMMAND_SETCAMERAPICTURE, c->value); 12036ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.picture = c->value; 12046ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12056ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_JPEGQUAL: 12066ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.quality = c->value; 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12086ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_FRAMERATE: 12096ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.framerate = c->value; 12106ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12116ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf default: 12126ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 12136ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12156ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12176ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 12186ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12206ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) 12216ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 12226ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 12236ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf switch (c->id) { 12246ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_BRIGHTNESS: 122551270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil c->value = meye.brightness >> 10; 12266ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12276ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_HUE: 122851270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil c->value = meye.hue >> 10; 12296ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12306ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_CONTRAST: 123151270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil c->value = meye.contrast >> 10; 12326ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12336ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_SATURATION: 123451270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil c->value = meye.colour >> 10; 12356ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12366ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_AGC: 12376ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->value = meye.params.agc; 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12396ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_SHARPNESS: 12406ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_MEYE_SHARPNESS: 12416ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->value = meye.params.sharpness; 12426ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12436ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_PICTURE: 12446ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->value = meye.params.picture; 12456ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12466ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_JPEGQUAL: 12476ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->value = meye.params.quality; 12486ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12496ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_CID_FRAMERATE: 12506ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf c->value = meye.params.framerate; 12516ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 12526ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf default: 12536ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 12546ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12566ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 12576ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 12586ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 12596ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 126178b526a43561d7e5e702ba27948e422dfbc4bea1Hans Verkuilstatic int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, 12626ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf struct v4l2_fmtdesc *f) 12636ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 12646ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (f->index > 1) 12656ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12676ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (f->index == 0) { 12686ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf /* standard YUV 422 capture */ 12696ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->flags = 0; 12706ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(f->description, "YUV422"); 12716ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->pixelformat = V4L2_PIX_FMT_YUYV; 12726ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf } else { 12736ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf /* compressed MJPEG capture */ 12746ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->flags = V4L2_FMT_FLAG_COMPRESSED; 12756ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf strcpy(f->description, "MJPEG"); 12766ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->pixelformat = V4L2_PIX_FMT_MJPEG; 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12796ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 12806ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 128278b526a43561d7e5e702ba27948e422dfbc4bea1Hans Verkuilstatic int vidioc_try_fmt_vid_cap(struct file *file, void *fh, 12836ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf struct v4l2_format *f) 12846ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 12856ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV && 12866ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) 12876ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 12886ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 12896ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (f->fmt.pix.field != V4L2_FIELD_ANY && 12906ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.field != V4L2_FIELD_NONE) 12916ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 12926ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 12936ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.field = V4L2_FIELD_NONE; 12946ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 12956ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (f->fmt.pix.width <= 320) { 12966ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.width = 320; 12976ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.height = 240; 12986ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf } else { 12996ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.width = 640; 13006ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.height = 480; 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13036ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 13046ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.sizeimage = f->fmt.pix.height * 13056ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.bytesperline; 13066ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.colorspace = 0; 13076ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.priv = 0; 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13096ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 13106ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 13116ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 131278b526a43561d7e5e702ba27948e422dfbc4bea1Hans Verkuilstatic int vidioc_g_fmt_vid_cap(struct file *file, void *fh, 131378b526a43561d7e5e702ba27948e422dfbc4bea1Hans Verkuil struct v4l2_format *f) 13146ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 13156ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf switch (meye.mchip_mode) { 13166ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MCHIP_HIC_MODE_CONT_OUT: 13176ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf default: 13186ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 13196ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 13206ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MCHIP_HIC_MODE_CONT_COMP: 13216ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13256ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.field = V4L2_FIELD_NONE; 13266ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.width = mchip_hsize(); 13276ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.height = mchip_vsize(); 13286ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 13296ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.sizeimage = f->fmt.pix.height * 13306ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.bytesperline; 13316ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 13326ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 13336ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 13346ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 133578b526a43561d7e5e702ba27948e422dfbc4bea1Hans Verkuilstatic int vidioc_s_fmt_vid_cap(struct file *file, void *fh, 133678b526a43561d7e5e702ba27948e422dfbc4bea1Hans Verkuil struct v4l2_format *f) 13376ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 13386ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV && 13396ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) 13406ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 13416ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 13426ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (f->fmt.pix.field != V4L2_FIELD_ANY && 13436ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.field != V4L2_FIELD_NONE) 13446ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 13456ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 13466ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.field = V4L2_FIELD_NONE; 13476ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 13486ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 13496ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (f->fmt.pix.width <= 320) { 13506ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.width = 320; 13516ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.height = 240; 13526ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.subsample = 1; 13536ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf } else { 13546ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.width = 640; 13556ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.height = 480; 13566ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.params.subsample = 0; 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13596ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf switch (f->fmt.pix.pixelformat) { 13606ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_PIX_FMT_YUYV: 13616ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT; 13626ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 13636ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case V4L2_PIX_FMT_MJPEG: 13646ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP; 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13686ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 13696ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 13706ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.sizeimage = f->fmt.pix.height * 13716ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.bytesperline; 13726ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.colorspace = 0; 13736ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf f->fmt.pix.priv = 0; 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13756ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 13766ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13786ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_reqbufs(struct file *file, void *fh, 13796ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf struct v4l2_requestbuffers *req) 13806ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 13816ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf int i; 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13836ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (req->memory != V4L2_MEMORY_MMAP) 13846ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13866ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.grab_fbuffer && req->count == gbuffers) { 13876ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf /* already allocated, no modifications */ 13886ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13916ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 13926ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.grab_fbuffer) { 13936ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf for (i = 0; i < gbuffers; i++) 13946ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.vma_use_count[i]) { 13956ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 13966ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 13976ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf } 13986ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf rvfree(meye.grab_fbuffer, gbuffers * gbufsize); 13996ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_fbuffer = NULL; 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14026ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf gbuffers = max(2, min((int)req->count, MEYE_MAX_BUFNBRS)); 14036ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf req->count = gbuffers; 14046ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize); 14056ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14066ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (!meye.grab_fbuffer) { 14076ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf printk(KERN_ERR "meye: v4l framebuffer allocation" 14086ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf " failed\n"); 14093593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&meye.lock); 14106ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -ENOMEM; 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14136ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf for (i = 0; i < gbuffers; i++) 14146ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.vma_use_count[i] = 0; 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14166ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14186ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 14196ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 14206ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14216ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) 14226ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 14236174523c5948f8a36f778f0abdfc648a5d73bf46Trent Piepho unsigned int index = buf->index; 14246ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14256174523c5948f8a36f778f0abdfc648a5d73bf46Trent Piepho if (index >= gbuffers) 14266ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 14276ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14286ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->bytesused = meye.grab_buffer[index].size; 14296ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->flags = V4L2_BUF_FLAG_MAPPED; 14306ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14316ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.grab_buffer[index].state == MEYE_BUF_USING) 14326ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->flags |= V4L2_BUF_FLAG_QUEUED; 14336ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14346ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.grab_buffer[index].state == MEYE_BUF_DONE) 14356ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->flags |= V4L2_BUF_FLAG_DONE; 14366ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14376ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->field = V4L2_FIELD_NONE; 14386ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->timestamp = meye.grab_buffer[index].timestamp; 14396ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->sequence = meye.grab_buffer[index].sequence; 14406ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->memory = V4L2_MEMORY_MMAP; 14416ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->m.offset = index * gbufsize; 14426ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->length = gbufsize; 14436ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14446ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 14456ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 14466ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14476ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) 14486ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 14496ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (buf->memory != V4L2_MEMORY_MMAP) 14506ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 14516ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14526174523c5948f8a36f778f0abdfc648a5d73bf46Trent Piepho if (buf->index >= gbuffers) 14536ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 14546ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14556ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED) 14566ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 14576ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14586ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 14596ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->flags |= V4L2_BUF_FLAG_QUEUED; 14606ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->flags &= ~V4L2_BUF_FLAG_DONE; 14616ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_buffer[buf->index].state = MEYE_BUF_USING; 14627acd72eb85f1c7a15e8b5eb554994949241737f1Stefani Seibold kfifo_in_locked(&meye.grabq, (unsigned char *)&buf->index, 1463c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold sizeof(int), &meye.grabq_lock); 14646ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 14656ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14666ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 14676ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 14686ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14696ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) 14706ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 14716ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf int reqnr; 14726ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14736ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (buf->memory != V4L2_MEMORY_MMAP) 14746ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 14756ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 14766ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 14776ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 147845465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold if (kfifo_len(&meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { 14793593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&meye.lock); 14806ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EAGAIN; 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14836ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (wait_event_interruptible(meye.proc_list, 148445465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold kfifo_len(&meye.doneq) != 0) < 0) { 14853593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&meye.lock); 14866ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINTR; 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14897acd72eb85f1c7a15e8b5eb554994949241737f1Stefani Seibold if (!kfifo_out_locked(&meye.doneq, (unsigned char *)&reqnr, 1490c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold sizeof(int), &meye.doneq_lock)) { 14916ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 14926ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EBUSY; 14936ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf } 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14956ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) { 14963593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&meye.lock); 14976ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 14981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15006ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->index = reqnr; 15016ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->bytesused = meye.grab_buffer[reqnr].size; 15026ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->flags = V4L2_BUF_FLAG_MAPPED; 15036ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->field = V4L2_FIELD_NONE; 15046ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->timestamp = meye.grab_buffer[reqnr].timestamp; 15056ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->sequence = meye.grab_buffer[reqnr].sequence; 15066ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->memory = V4L2_MEMORY_MMAP; 15076ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->m.offset = reqnr * gbufsize; 15086ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf buf->length = gbufsize; 15096ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED; 15106ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 15116ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15126ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 15136ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15156ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) 15166ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 15176ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 15186ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15196ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf switch (meye.mchip_mode) { 15206ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MCHIP_HIC_MODE_CONT_OUT: 15216ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mchip_continuous_start(); 15226ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 15236ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MCHIP_HIC_MODE_CONT_COMP: 15246ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mchip_cont_compression_start(); 15256ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf break; 15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 15276ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 15286ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15316ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 15326ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15366ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgrafstatic int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15386ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_lock(&meye.lock); 15396ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mchip_hic_stop(); 154045465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold kfifo_reset(&meye.grabq); 154145465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold kfifo_reset(&meye.doneq); 15426ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15436ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf for (i = 0; i < MEYE_MAX_BUFNBRS; i++) 15446ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf meye.grab_buffer[i].state = MEYE_BUF_UNUSED; 15456ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15466ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf mutex_unlock(&meye.lock); 15476ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return 0; 15486ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf} 15496ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 155099cd47bc733436da282016e629eef6baa0f6047cHans Verkuilstatic long vidioc_default(struct file *file, void *fh, bool valid_prio, 155199cd47bc733436da282016e629eef6baa0f6047cHans Verkuil int cmd, void *arg) 15526ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf{ 15536ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf switch (cmd) { 15546ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MEYEIOC_G_PARAMS: 15556ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return meyeioc_g_params((struct meye_params *) arg); 15566ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15576ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MEYEIOC_S_PARAMS: 15586ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return meyeioc_s_params((struct meye_params *) arg); 15596ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15606ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MEYEIOC_QBUF_CAPT: 15616ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return meyeioc_qbuf_capt((int *) arg); 15626ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15636ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MEYEIOC_SYNC: 15646ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return meyeioc_sync(file, fh, (int *) arg); 15656ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15666ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MEYEIOC_STILLCAPT: 15676ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return meyeioc_stillcapt(); 15686ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15696ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf case MEYEIOC_STILLJCAPT: 15706ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return meyeioc_stilljcapt((int *) arg); 15716ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15726ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf default: 15736ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf return -EINVAL; 15746ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf } 15756ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf 15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int meye_poll(struct file *file, poll_table *wait) 15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int res = 0; 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15823593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_lock(&meye.lock); 15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &meye.proc_list, wait); 158445465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold if (kfifo_len(&meye.doneq)) 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res = POLLIN | POLLRDNORM; 15863593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&meye.lock); 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return res; 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void meye_vm_open(struct vm_area_struct *vma) 15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1592d6144028af6b151018c50c160e794a4d7f686333Mauro Carvalho Chehab long idx = (long)vma->vm_private_data; 15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.vma_use_count[idx]++; 15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void meye_vm_close(struct vm_area_struct *vma) 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1598d6144028af6b151018c50c160e794a4d7f686333Mauro Carvalho Chehab long idx = (long)vma->vm_private_data; 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.vma_use_count[idx]--; 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1602f0f37e2f77731b3473fa6bd5ee53255d9a9cdb40Alexey Dobriyanstatic const struct vm_operations_struct meye_vm_ops = { 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = meye_vm_open, 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .close = meye_vm_close, 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int meye_mmap(struct file *file, struct vm_area_struct *vma) 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long start = vma->vm_start; 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long size = vma->vm_end - vma->vm_start; 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long page, pos; 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16143593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_lock(&meye.lock); 16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (size > gbuffers * gbufsize) { 16163593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&meye.lock); 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!meye.grab_fbuffer) { 16201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* lazy allocation */ 16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize); 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!meye.grab_fbuffer) { 16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "meye: v4l framebuffer allocation failed\n"); 16263593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&meye.lock); 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < gbuffers; i++) 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.vma_use_count[i] = 0; 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pos = (unsigned long)meye.grab_fbuffer + offset; 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (size > 0) { 16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page = vmalloc_to_pfn((void *)pos); 16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { 16373593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&meye.lock); 16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EAGAIN; 16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start += PAGE_SIZE; 16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pos += PAGE_SIZE; 16421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (size > PAGE_SIZE) 16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size -= PAGE_SIZE; 16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = 0; 16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vma->vm_ops = &meye_vm_ops; 16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vma->vm_flags &= ~VM_IO; /* not I/O memory */ 16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ 16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vma->vm_private_data = (void *) (offset / gbufsize); 16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye_vm_open(vma); 16531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16543593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&meye.lock); 16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 16561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1658bec43661b1dc0075b7445223ba775674133b164dHans Verkuilstatic const struct v4l2_file_operations meye_fops = { 16591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = meye_open, 16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = meye_release, 16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .mmap = meye_mmap, 166361df3c9b3fe6a7e47d25b27ae4df0ecdb07b8fbdHans Verkuil .unlocked_ioctl = video_ioctl2, 16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll = meye_poll, 16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1667a399810ca69d9d4bd30ab8c1678c7439e567f90bHans Verkuilstatic const struct v4l2_ioctl_ops meye_ioctl_ops = { 16686ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_querycap = vidioc_querycap, 16696ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_enum_input = vidioc_enum_input, 16706ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_g_input = vidioc_g_input, 16716ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_s_input = vidioc_s_input, 16726ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_queryctrl = vidioc_queryctrl, 16736ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_s_ctrl = vidioc_s_ctrl, 16746ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_g_ctrl = vidioc_g_ctrl, 167578b526a43561d7e5e702ba27948e422dfbc4bea1Hans Verkuil .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 167678b526a43561d7e5e702ba27948e422dfbc4bea1Hans Verkuil .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 167778b526a43561d7e5e702ba27948e422dfbc4bea1Hans Verkuil .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 167878b526a43561d7e5e702ba27948e422dfbc4bea1Hans Verkuil .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 16796ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_reqbufs = vidioc_reqbufs, 16806ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_querybuf = vidioc_querybuf, 16816ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_qbuf = vidioc_qbuf, 16826ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_dqbuf = vidioc_dqbuf, 16836ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_streamon = vidioc_streamon, 16846ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_streamoff = vidioc_streamoff, 16856ec6e0ced1bb9d85e29302e76f5340e3e49bd0b9Douglas Schilling Landgraf .vidioc_default = vidioc_default, 16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1688a399810ca69d9d4bd30ab8c1678c7439e567f90bHans Verkuilstatic struct video_device meye_template = { 1689a399810ca69d9d4bd30ab8c1678c7439e567f90bHans Verkuil .name = "meye", 1690a399810ca69d9d4bd30ab8c1678c7439e567f90bHans Verkuil .fops = &meye_fops, 1691a399810ca69d9d4bd30ab8c1678c7439e567f90bHans Verkuil .ioctl_ops = &meye_ioctl_ops, 1692a399810ca69d9d4bd30ab8c1678c7439e567f90bHans Verkuil .release = video_device_release, 1693a399810ca69d9d4bd30ab8c1678c7439e567f90bHans Verkuil}; 1694a399810ca69d9d4bd30ab8c1678c7439e567f90bHans Verkuil 16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PM 1696a291068991c4d0cc4c2bd533094422bf417c86ddPavel Machekstatic int meye_suspend(struct pci_dev *pdev, pm_message_t state) 16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_save_state(pdev); 16991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.pm_mchip_mode = meye.mchip_mode; 17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_hic_stop(); 17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MM_INTA, 0x0); 17021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int meye_resume(struct pci_dev *pdev) 17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_restore_state(pdev); 17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1); 17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_CMD, 0); 17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE); 17121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 17131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_SOFT_RESET, 1); 17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 17151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MM_PCI_MODE, 5); 17161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); 17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (meye.pm_mchip_mode) { 17201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MCHIP_HIC_MODE_CONT_OUT: 17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_continuous_start(); 17221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MCHIP_HIC_MODE_CONT_COMP: 17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_cont_compression_start(); 17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 17301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __devinit meye_probe(struct pci_dev *pcidev, 17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const struct pci_device_id *ent) 17331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 173451270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil struct v4l2_device *v4l2_dev = &meye.v4l2_dev; 17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = -EBUSY; 17361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long mchip_adr; 17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (meye.mchip_dev != NULL) { 17391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "meye: only one device allowed!\n"); 17401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outnotdev; 17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 174351270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil ret = v4l2_device_register(&pcidev->dev, v4l2_dev); 174451270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil if (ret < 0) { 174551270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 174651270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil return ret; 174751270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil } 1748ef0e3c26efe9c52de62b96fdad94de3ed70489d0Henrik Kretzschmar ret = -ENOMEM; 17491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_dev = pcidev; 175051270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil meye.vdev = video_device_alloc(); 175151270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil if (!meye.vdev) { 175251270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "video_device_alloc() failed!\n"); 17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outnotdev; 17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE); 17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!meye.grab_temp) { 175851270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "grab buffer allocation failed\n"); 17591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outvmalloc; 17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&meye.grabq_lock); 1763c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, 1764c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold GFP_KERNEL)) { 176551270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "fifo allocation failed\n"); 17661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outkfifoalloc1; 17671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&meye.doneq_lock); 1769c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, 1770c1e13f25674ed564948ecb7dfe5f83e578892896Stefani Seibold GFP_KERNEL)) { 177151270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "fifo allocation failed\n"); 17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outkfifoalloc2; 17731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 177551270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil memcpy(meye.vdev, &meye_template, sizeof(meye_template)); 177651270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil meye.vdev->v4l2_dev = &meye.v4l2_dev; 17771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17785b5aff83a549c8f1e425e06d46ec951eae950b37Mauro Carvalho Chehab ret = -EIO; 1779cbefb762b67fa6d3eb2a48ae3380358a940e8c9dmalattia@linux.it if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) { 178051270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "meye: unable to power on the camera\n"); 178151270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "meye: did you enable the camera in " 17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "sonypi using the module options ?\n"); 17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outsonypienable; 17841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = pci_enable_device(meye.mchip_dev))) { 178751270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "meye: pci_enable_device failed\n"); 17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outenabledev; 17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_adr = pci_resource_start(meye.mchip_dev,0); 17921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!mchip_adr) { 179351270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "meye: mchip has no device base address\n"); 17941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outregions; 17951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0), 17971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_resource_len(meye.mchip_dev, 0), 17981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "meye")) { 179951270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "meye: request_mem_region failed\n"); 18001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outregions; 18011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS); 18031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!meye.mchip_mmregs) { 180451270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "meye: ioremap failed\n"); 18051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outremap; 18061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.mchip_irq = pcidev->irq; 18091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (request_irq(meye.mchip_irq, meye_irq, 18108076fe32a7db9a6628589ffa372808e4ba25d222Thomas Gleixner IRQF_DISABLED | IRQF_SHARED, "meye", meye_irq)) { 181151270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_err(v4l2_dev, "request_irq failed\n"); 18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outreqirq; 18131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8); 18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64); 18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_set_master(meye.mchip_dev); 18191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Ask the camera to perform a soft reset. */ 18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1); 18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_CMD, 0); 18241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE); 18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 18271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_VRJ_SOFT_RESET, 1); 18281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MM_PCI_MODE, 5); 18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); 18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18353593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_init(&meye.lock); 18361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_waitqueue_head(&meye.proc_list); 183751270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil meye.brightness = 32 << 10; 183851270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil meye.hue = 32 << 10; 183951270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil meye.colour = 32 << 10; 184051270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil meye.contrast = 32 << 10; 18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.params.subsample = 0; 18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.params.quality = 8; 18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.params.sharpness = 32; 18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.params.agc = 48; 18451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.params.picture = 0; 18461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.params.framerate = 0; 18471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1848cbefb762b67fa6d3eb2a48ae3380358a940e8c9dmalattia@linux.it sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, 32); 1849cbefb762b67fa6d3eb2a48ae3380358a940e8c9dmalattia@linux.it sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAHUE, 32); 1850cbefb762b67fa6d3eb2a48ae3380358a940e8c9dmalattia@linux.it sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACOLOR, 32); 1851cbefb762b67fa6d3eb2a48ae3380358a940e8c9dmalattia@linux.it sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACONTRAST, 32); 1852cbefb762b67fa6d3eb2a48ae3380358a940e8c9dmalattia@linux.it sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERASHARPNESS, 32); 1853cbefb762b67fa6d3eb2a48ae3380358a940e8c9dmalattia@linux.it sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0); 1854cbefb762b67fa6d3eb2a48ae3380358a940e8c9dmalattia@linux.it sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48); 18551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 185661df3c9b3fe6a7e47d25b27ae4df0ecdb07b8fbdHans Verkuil if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, 185761df3c9b3fe6a7e47d25b27ae4df0ecdb07b8fbdHans Verkuil video_nr) < 0) { 185861df3c9b3fe6a7e47d25b27ae4df0ecdb07b8fbdHans Verkuil v4l2_err(v4l2_dev, "video_register_device failed\n"); 185961df3c9b3fe6a7e47d25b27ae4df0ecdb07b8fbdHans Verkuil goto outvideoreg; 186061df3c9b3fe6a7e47d25b27ae4df0ecdb07b8fbdHans Verkuil } 186161df3c9b3fe6a7e47d25b27ae4df0ecdb07b8fbdHans Verkuil 186251270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n", 18631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MEYE_DRIVER_VERSION); 186451270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n", 186544c10138fd4bbc4b6d6bff0873c24902f2a9da65Auke Kok meye.mchip_dev->revision, mchip_adr, meye.mchip_irq); 18661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 18681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsoutvideoreg: 18701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(meye.mchip_irq, meye_irq); 18711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsoutreqirq: 18721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(meye.mchip_mmregs); 18731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsoutremap: 18741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_mem_region(pci_resource_start(meye.mchip_dev, 0), 18751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_resource_len(meye.mchip_dev, 0)); 18761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsoutregions: 18771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_disable_device(meye.mchip_dev); 18781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsoutenabledev: 1879cbefb762b67fa6d3eb2a48ae3380358a940e8c9dmalattia@linux.it sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); 18801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsoutsonypienable: 188145465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold kfifo_free(&meye.doneq); 18821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsoutkfifoalloc2: 188345465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold kfifo_free(&meye.grabq); 18841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsoutkfifoalloc1: 18851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vfree(meye.grab_temp); 18861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsoutvmalloc: 188751270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil video_device_release(meye.vdev); 18881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsoutnotdev: 18891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 18901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __devexit meye_remove(struct pci_dev *pcidev) 18931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 189451270617a52793c423ef68ddd3f18745e9abd15bHans Verkuil video_unregister_device(meye.vdev); 18951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_hic_stop(); 18971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_dma_free(); 18991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* disable interrupts */ 19011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchip_set(MCHIP_MM_INTA, 0x0); 19021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(meye.mchip_irq, meye_irq); 19041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(meye.mchip_mmregs); 19061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_mem_region(pci_resource_start(meye.mchip_dev, 0), 19081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_resource_len(meye.mchip_dev, 0)); 19091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_disable_device(meye.mchip_dev); 19111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1912cbefb762b67fa6d3eb2a48ae3380358a940e8c9dmalattia@linux.it sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); 19131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 191445465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold kfifo_free(&meye.doneq); 191545465487897a1c6d508b14b904dc5777f7ec7e04Stefani Seibold kfifo_free(&meye.grabq); 19161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vfree(meye.grab_temp); 19181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (meye.grab_fbuffer) { 19201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rvfree(meye.grab_fbuffer, gbuffers*gbufsize); 19211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds meye.grab_fbuffer = NULL; 19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "meye: removed\n"); 19251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 19261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_device_id meye_pci_tbl[] = { 192876e9741d1d7deb332abbbc3d8fc4c55154e2c180Joe Perches { PCI_VDEVICE(KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002), 0 }, 19291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { } 19301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 19311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DEVICE_TABLE(pci, meye_pci_tbl); 19331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_driver meye_driver = { 19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "meye", 19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .id_table = meye_pci_tbl, 19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .probe = meye_probe, 19381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .remove = __devexit_p(meye_remove), 19391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PM 19401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .suspend = meye_suspend, 19411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .resume = meye_resume, 19421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 19431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 19441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init meye_init(void) 19461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 19471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gbuffers = max(2, min((int)gbuffers, MEYE_MAX_BUFNBRS)); 19481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE) 19491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gbufsize = MEYE_MAX_BUFSIZE; 19501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gbufsize = PAGE_ALIGN(gbufsize); 1951ac9bb7f5167d53207893a783a2f722cd6e6ed78fJoe Perches printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) " 19521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "for capture\n", 19531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gbuffers, 19541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gbufsize / 1024, gbuffers * gbufsize / 1024); 19551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pci_register_driver(&meye_driver); 19561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 19571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit meye_exit(void) 19591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 19601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_unregister_driver(&meye_driver); 19611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 19621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(meye_init); 19641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(meye_exit); 1965