os/linux-2.6-tag--devboard-R2_10-4/arch/cris/arch-v32/drivers/elphel/ext353.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007 Elphel, Inc
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation, either version 3 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #include <linux/kernel.h>
00019 #include <linux/sched.h>
00020 #include <linux/mm.h>
00021 //#include <linux/tqueue.h>
00022 #include <linux/wait.h>
00023 
00024 #include <asm/unistd.h>
00025 #include <asm/semaphore.h>
00026 //#include <asm/smplock.h>
00027 #include <asm/atomic.h>
00028 
00029 #include <linux/module.h>
00030 #include <linux/slab.h>
00031 #include <linux/errno.h>
00032 #include <linux/fs.h>
00033 #include <linux/string.h>
00034 #include <linux/init.h>
00035 #include <linux/mm.h>
00036 //#include <linux/iobuf.h>
00037 //#include <linux/compatmac.h>
00038 #include <linux/vmalloc.h>
00039 #include <linux/rwsem.h>
00040 
00041 #include <linux/netdevice.h>
00042 #include <linux/skbuff.h>
00043 #include <linux/time.h>
00044 #include <linux/wait.h>
00045 #include <asm/io.h>
00046 #include <asm/atomic.h>
00047 #include <asm/page.h>
00048 //#include <linux/wrapper.h>
00049 
00050 #include "fpgactrl.h"  // defines port_csp0_addr, port_csp4_addr 
00051 
00052 #include <asm/elphel/ext353.h>
00053 #include <asm/elphel/c313a.h>
00054 
00055 #include "fpgactrl.h"  // defines port_csp0_addr, port_csp4_addr 
00056 
00057 #include "x3x3.h"
00058 //#include "cc3x3.h"
00059 #include "cxdma.h"
00060 #include "exif.h"
00061 
00062 #define EXT353_MAJOR 124
00063 
00064 extern unsigned long *ccam_dma;
00065 extern unsigned long t_sign;
00066 //------------------------------------------------------------------------------
00067 
00068 struct image_t image = {
00069         .tv_sec = 0,
00070         .tv_usec = 0,
00071 };
00072 
00073 unsigned char exif_header[] = {
00074         //.....PExif..MM.*.............A...b......
00075         0xFF,0xD8,0xFF,0xE1, 0x01,0x50,0x45,0x78, 0x69,0x66,0x00,0x00, 0x4D,0x4D,0x00,0x2A,
00076         0x00,0x00,0x00,0x08, 0x00,0x07,0x01,0x0E, 0x00,0x02,0x00,0x00, 0x00,0x41,0x00,0x00,
00077         0x00,0x62,0x01,0x0F, 0x00,0x02,0x00,0x00,
00078 
00079         //...................1...........2........
00080         0x00,0x0C,0x00,0x00, 0x00,0xA4,0x01,0x10,
00081         0x00,0x02,0x00,0x00, 0x00,0x07,0x00,0x00, 0x00,0xB0,0x01,0x31, 0x00,0x02,0x00,0x00,
00082         0x00,0x1C,0x00,0x00, 0x00,0xB8,0x01,0x32, 0x00,0x02,0x00,0x00, 0x00,0x14,0x00,0x00,
00083 
00084         //...;...........i..............Seq:010203
00085         0x00,0xD4,0x01,0x3B, 0x00,0x02,0x00,0x00, 0x00,0x12,0x00,0x00, 0x00,0xE8,0x87,0x69,
00086 //      0x00,0x04,0x00,0x00, 0x00,0x01,0x00,0x00, 0x00,0xFA,0x00,0x00, 0x00,0x00,0x53,0x65,
00087         0x00,0x04,0x00,0x00, 0x00,0x01,0x00,0x00, 0x00,0xFA,0x00,0x00, 0x00,0x00,0x20,0x00,
00088         0x71,0x3A,0x30,0x31, 0x30,0x32,0x30,0x33,
00089 
00090         //04;Trig:00000001______==================
00091         0x30,0x34,0x3B,0x54, 0x72,0x69,0x67,0x3A,
00092         0x30,0x30,0x30,0x30, 0x30,0x30,0x30,0x31, 0x5F,0x5F,0x5F,0x5F, 0x5F,0x5F,0x3D,0x3D,
00093         0x3D,0x3D,0x3D,0x3D, 0x3D,0x3D,0x3D,0x3D, 0x3D,0x3D,0x3D,0x3D, 0x3D,0x3D,0x3D,0x3D,
00094 
00095         //==============..Elphel, Inc.323   ..c323
00096         0x3D,0x3D,0x3D,0x3D, 0x3D,0x3D,0x3D,0x3D, 0x3D,0x3D,0x3D,0x3D, 0x3D,0x3D,0x00,0x00,
00097         0x45,0x6C,0x70,0x68, 0x65,0x6C,0x2C,0x20, 0x49,0x6E,0x63,0x00, 0x33,0x35,0x33,0x20,
00098         0x20,0x20,0x00,0x00, 0x63,0x33,0x35,0x33,
00099 
00100         // 6.3.3.2-01234567890AB .2007:05:31 17:10
00101         0x20,0x36,0x2E,0x33, 0x2E,0x33,0x2E,0x32,
00102         0x2D,0x30,0x31,0x32, 0x33,0x34,0x35,0x36, 0x37,0x38,0x39,0x30, 0x41,0x42,0x20,0x00,
00103         0x32,0x30,0x30,0x37, 0x3A,0x30,0x35,0x3A, 0x33,0x31,0x20,0x31, 0x37,0x3A,0x31,0x30,
00104 
00105         //:48.00:0E:64:32:30:10..............$....
00106         0x3A,0x34,0x38,0x00, 0x30,0x30,0x3A,0x30,
00107         0x45,0x3A,0x36,0x34, 0x3A,0x33,0x32,0x3A, 0x33,0x30,0x3A,0x31, 0x30,0x00,0x00,0x03,
00108         0x82,0x9A,0x00,0x05, 0x00,0x00,0x00,0x01, 0x00,0x00,0x01,0x24, 0x90,0x03,0x00,0x02,
00109 
00110         //.......,...........@............2007:05:
00111         0x00,0x00,0x00,0x14, 0x00,0x00,0x01,0x2C,
00112         0x92,0x91,0x00,0x02, 0x00,0x00,0x00,0x07, 0x00,0x00,0x01,0x40, 0x00,0x00,0x00,0x00,
00113         0x00,0x00,0x89,0xC4, 0x00,0x00,0x03,0xE8, 0x32,0x30,0x30,0x37, 0x3A,0x30,0x35,0x3A,
00114 
00115         //31 17:10:48.857266......JFIF............
00116         0x33,0x31,0x20,0x31, 0x37,0x3A,0x31,0x30,
00117         0x3A,0x34,0x38,0x00, 0x38,0x35,0x37,0x32, 0x36,0x36,0x00,0x00, 0xFF,0xE0
00118 //      0x33,0x31,0x20,0x31, 0x37,0x3A,0x31,0x30,
00119 //      0x3A,0x34,0x38,0x00, 0x38,0x35,0x37,0x32, 0x36,0x36,0x00,0x00, 0xFF,0xE0,0x00,0x10,
00120 //      0x4A,0x46,0x49,0x46, 0x00,0x01,0x01,0x00, 0x00,0x01,0x00,0x01, 0x00,0x00,0xFF,0xDB,
00121 };
00122 
00123 int exif_header_length(void) {
00124         return sizeof(exif_header);
00125 }
00126 
00127 struct exif_desc_t exif_desc = {
00128         .date_time = {
00129                 '1', '9', '7', '0', ':', '0', '1', ':', '3', '2', ' ', '2', '3', ':', '5', '9', ':', '5', '9', '\0'
00130         },
00131         .date_time_or = {
00132                 '1', '9', '7', '0', ':', '0', '1', ':', '3', '2', ' ', '2', '3', ':', '5', '9', ':', '6', '0', '\0'
00133         },
00134         .subsec = {
00135                 '0', '0', '0', '0', '0', '1', '\0'
00136         },
00137         .artist = {
00138                 'M', 'A', ':', 'C', ' ', ':', 'E', 'T', ':', 'H', 'E', ':', 'R', 'N', ':', 'E', 'T', '\0'
00139         },
00140         .firmware = {
00141                 'c', '3', '5', '3', ' ', ' ', ' ', ' ', ' ', ' ',
00142                 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
00143                 ' ', ' ', ' ', ' ', ' ', ' ', ' ',
00144         },
00145         .exp = { 1, 10000 },
00146 };
00147 
00148 void get_image_time(unsigned long *t) {
00149         struct timeval tv;
00150         do_gettimeofday(&tv);
00151         t[0] = tv.tv_sec;
00152         t[1] = tv.tv_usec;
00153         unsigned long jpeg_wp = camSeqGetJPEG_wp();
00154         int i = 0;
00155 //printk("system_time  == %d:%06d\n", (int) t[0], (int)t[1]);
00156 //printk("jpeg_wp      == 0x%08X\n", (int) jpeg_wp);
00157 //printk("ccam_dma == 0x%08X\n", (int) ccam_dma);
00158         for(i = 0; i < 20; i++) {
00159 //              printk("ccam_dma[0 - %d] == 0x%08X\n", i, (int) ccam_dma[jpeg_wp - i]);
00160                 if(ccam_dma[jpeg_wp - i] == t_sign) {
00161                         t[1] = ccam_dma[jpeg_wp - i - 1];
00162                         t[0] = ccam_dma[jpeg_wp - i - 2];
00163                 i--;
00164 //              printk("!!! ccam_dma[0 - %d] == 0x%08X\n", i, (int) ccam_dma[jpeg_wp - i]);
00165                 i--;
00166 //              printk("!!! ccam_dma[0 - %d] == 0x%08X\n", i, (int) ccam_dma[jpeg_wp - i]);
00167                         break;
00168                 }
00169         }
00170 //printk("FPGA_time    == %d:%06d\n\n", (int) t[0], (int) t[1]);
00171 }
00172 
00173 /*******************************************************************************
00174  *
00175  *
00176  */
00177 
00178 static int ext353__open(struct inode *inode, struct file *filp);
00179 static int ext353__ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
00180 static int ext353__release(struct inode *inode, struct file *filp);
00181 static int ext353__mmap(struct file *filp, struct vm_area_struct *vma);
00182 
00183 static struct file_operations ext353__fops = {
00184         owner:          THIS_MODULE,
00185         open:           ext353__open,
00186         ioctl:          ext353__ioctl,
00187         mmap:           ext353__mmap,
00188         release:        ext353__release,
00189 };
00190 
00191 int ext353__open(struct inode *inode, struct file *filp) {
00192         return 0;
00193 }
00194 
00195 static int ext353__mmap(struct file *filp, struct vm_area_struct *vma) {
00196         struct _ext_jpeg_mmap_desc_t mdesc;
00197         ext_fill_jpeg_mmap_desc_(&mdesc);
00198         int rez = 0;
00199 //      long off = 0;
00200         if(vma->vm_end - vma->vm_start == mdesc.exif_length)
00201                 rez = remap_pfn_range(vma, vma->vm_start, ((unsigned long)mdesc.exif_start) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot);
00202         if(vma->vm_end - vma->vm_start == mdesc.jpeg_length)
00203                 rez = remap_pfn_range(vma, vma->vm_start, ((unsigned long)mdesc.jpeg_start) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot);
00204 /*
00205 //      rez = remap_pfn_range(vma, vma->vm_start, virt_to_phys(mdesc.exif_start), mdesc.exif_length, vma->vm_page_prot);
00206         off += mdesc.exif_length;
00207         remap_pfn_range(vma, vma->vm_start + off, virt_to_phys(mdesc.jpeg_start), mdesc.jpeg_length, vma->vm_page_prot);
00208         off += mdesc.jpeg_length;
00209         remap_pfn_range(vma, vma->vm_start + off, virt_to_phys(mdesc.jpeg_start), mdesc.jpeg_length, vma->vm_page_prot);
00210 //      int rez = remap_pfn_range(vma, vma->vm_start, virt_to_phys(b->buf) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot);
00211 */
00212         return rez;
00213 }
00214 
00215 static int ext353__ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) {
00216         int ret = 0;
00217         unsigned long get_time_rez[4];
00218         struct timeval sys_1, sys_2;
00219 //printk("ext353 - ioctl!!!\n");
00220         switch(cmd) {
00221                 case EXIF_IOC_MAC_SET: {
00222 //printk("mac set\n");
00223                         copy_from_user(exif_desc.artist, (void *)arg, EXIF_ARTIST_LEN - 1);
00224                         break;
00225                 }
00226                 case EXIF_IOC_FIRMWARE_SET: {
00227 //printk("firmware set\n");
00228                         copy_from_user(exif_desc.firmware, (void *)arg, EXIF_FIRMWARE_LEN - 1);
00229                         break;
00230                 }
00231                 case EXIF_IOC_TIME_SET: {
00232                         copy_from_user(exif_desc.date_time, (void *)arg, EXIF_DATE_TIME_LEN - 1);
00233 //printk("time set: %s\n", exif_desc.date_time);
00234                         break;
00235                 }
00236                 case EXIF_IOC_TIME_OR_SET: {
00237                         copy_from_user(exif_desc.date_time_or, (void *)arg, EXIF_DATE_TIME_OR_LEN - 1);
00238 //printk("time_or set: %s\n", exif_desc.date_time_or);
00239                         break;
00240                 }
00241                 case EXIF_IOC_SUBSEC_OR_SET: {
00242 //printk("subsec_or set\n");
00243                         copy_from_user(exif_desc.subsec, (void *)arg, EXIF_SUBSEC_OR_LEN - 1);
00244                         break;
00245                 }
00246                 case EXIF_IOC_TIME_GET: {
00247                         unsigned long t[2];
00248                         get_image_time((unsigned long*) &t);
00249                         copy_to_user((void *)arg, (void *)t, sizeof(unsigned long) * 2);
00250 //printk("time get: %d:%d\n", (int) t[0], (int)t[1]);
00251                         break;
00252                 }
00253                 // TODO !!!
00254                 case EXT_JPEG_MMAP_DESC: {
00255                         struct ext_jpeg_mmap_desc_t mdesc;
00256                         ext_fill_jpeg_mmap_desc(&mdesc);
00257                         copy_to_user((struct ext_jpeg_mmap_desc_t *)arg, &mdesc, sizeof(struct ext_jpeg_mmap_desc_t));
00258                         break;
00259                 }
00260                 case EXT_GET_TIME_SYNC: {
00261                         do_gettimeofday(&sys_1);
00262                         // read FPGA time
00263                         port_csp0_addr[X313_WA_RTC_LATCH] = 0xFF;
00264                         get_time_rez[2] = port_csp0_addr[X313_RA_RTC_SEC];
00265                         get_time_rez[3] = port_csp0_addr[X313_RA_RTC_USEC];
00266                         do_gettimeofday(&sys_2);
00267                         unsigned long delta;
00268                         if(sys_2.tv_sec != sys_1.tv_sec)
00269                                 sys_2.tv_usec += 1000000;
00270                         delta = sys_2.tv_usec - sys_1.tv_usec;
00271                         sys_1.tv_usec += delta / 2;
00272                         if(sys_1.tv_usec >= 1000000) {
00273                                 sys_1.tv_usec -= 1000000;
00274                                 sys_1.tv_sec -= 1;
00275                         }
00276                         get_time_rez[0] = sys_1.tv_sec;
00277                         get_time_rez[1] = sys_1.tv_usec;
00278                         copy_to_user((void *)arg, (void *)&get_time_rez[0], 4 * sizeof(unsigned long));
00279                         break;
00280                 }
00281         }
00282         return ret;
00283 }
00284 
00285 int ext353__release(struct inode *inode, struct file *filp) {
00286         return 0;
00287 }
00288 
00289 static int __init ext353__init(void) {
00290         int res;
00291 
00292         /* register autoexposure device */
00293         res = register_chrdev(EXT353_MAJOR, "ext353", &ext353__fops);
00294         if(res < 0) {
00295                 printk(KERN_ERR "ext353: couldn't get a major number.\n");
00296                 return res;
00297         }
00298         return res;
00299 }
00300 
00301 static void __exit ext353__exit(void) {
00302         unregister_chrdev(EXT353_MAJOR, "ext353");
00303 }
00304 
00305 module_init(ext353__init);
00306 module_exit(ext353__exit);

Generated on Fri Nov 28 00:06:23 2008 for elphel by  doxygen 1.5.1