00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <linux/kernel.h>
00019 #include <linux/sched.h>
00020 #include <linux/mm.h>
00021
00022 #include <linux/wait.h>
00023
00024 #include <asm/unistd.h>
00025 #include <asm/semaphore.h>
00026
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
00037
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
00049
00050 #include "fpgactrl.h"
00051
00052 #include <asm/elphel/ext353.h>
00053 #include <asm/elphel/c313a.h>
00054
00055 #include "fpgactrl.h"
00056
00057 #include "x3x3.h"
00058
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
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
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
00085 0x00,0xD4,0x01,0x3B, 0x00,0x02,0x00,0x00, 0x00,0x12,0x00,0x00, 0x00,0xE8,0x87,0x69,
00086
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
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
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
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
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
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
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
00119
00120
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
00156
00157
00158 for(i = 0; i < 20; i++) {
00159
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
00165 i--;
00166
00167 break;
00168 }
00169 }
00170
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
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
00206
00207
00208
00209
00210
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
00220 switch(cmd) {
00221 case EXIF_IOC_MAC_SET: {
00222
00223 copy_from_user(exif_desc.artist, (void *)arg, EXIF_ARTIST_LEN - 1);
00224 break;
00225 }
00226 case EXIF_IOC_FIRMWARE_SET: {
00227
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
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
00239 break;
00240 }
00241 case EXIF_IOC_SUBSEC_OR_SET: {
00242
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
00251 break;
00252 }
00253
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
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
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);