00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define CCD_VERSION "V0.1 (C) P.Zahl 2000"
00038
00039
00040
00041
00042
00043
00044 #include <linux/config.h>
00045 #include <linux/module.h>
00046 #include <linux/pci.h>
00047 #include <linux/types.h>
00048 #include <linux/major.h>
00049 #include <linux/errno.h>
00050 #include <linux/signal.h>
00051 #include <linux/fcntl.h>
00052 #include <linux/sched.h>
00053 #include <linux/interrupt.h>
00054 #include <linux/devpts_fs.h>
00055 #include <linux/file.h>
00056 #include <linux/console.h>
00057 #include <linux/timer.h>
00058 #include <linux/ctype.h>
00059 #include <linux/kd.h>
00060 #include <linux/mm.h>
00061 #include <linux/string.h>
00062 #include <linux/poll.h>
00063 #include <linux/proc_fs.h>
00064 #include <linux/init.h>
00065 #include <linux/smp_lock.h>
00066 #include <linux/devfs_fs_kernel.h>
00067
00068 #include <asm/io.h>
00069 #include <asm/uaccess.h>
00070 #include <asm/system.h>
00071 #include <asm/bitops.h>
00072
00073 #include "ccd.h"
00074 #include "dbgstuff.h"
00075
00076
00077
00078
00079
00080
00081 static devfs_handle_t devfs_handle = NULL;
00082
00083 static int opened;
00084
00085
00086 static ccd_parport ccd_parport_io;
00087 static ccd_parport *ccd_io;
00088
00089
00090
00091 static DECLARE_WAIT_QUEUE_HEAD(waitq);
00092
00093
00094
00095
00096
00097 #define TIMEOUT_TICKS 19
00098 #define JIFFIES_SEM 2
00099 #define MAXWAKEUPS_SEM 10
00100
00101
00102
00103 static void timeout(unsigned long ignore);
00104 void mysleep(unsigned long myjiffies);
00105
00106
00107 static ssize_t ccd_read (struct file *, char *, size_t, loff_t *);
00108 static int ccd_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
00109
00110 int ccd_initialize(void);
00111 inline void ccd_quit(void);
00112
00113 int init_module(void);
00114 void cleanup_module(void);
00115
00116 static void timeout(unsigned long ignore){
00117 KDEBUG_L3("tmout wakeups %d\n", wakeups);
00118 wake_up_interruptible(&waitq);
00119 }
00120
00121 #define MAKE_MY_TIMEOUT_TMR(tmr) \
00122 struct timer_list tmr; \
00123 init_timer(&tmr); \
00124 tmr.function = timeout; \
00125 tmr.data = 0
00126
00127
00128 void mysleep(unsigned long myjiffies){
00129 MAKE_MY_TIMEOUT_TMR(timeout_tmr);
00130
00131 del_timer(&timeout_tmr);
00132 timeout_tmr.expires = jiffies + myjiffies;
00133 add_timer(&timeout_tmr);
00134 interruptible_sleep_on(&waitq);
00135 }
00136
00137
00138
00139
00140
00141
00142 static ssize_t ccd_read(struct file *f, char *buf, size_t count, loff_t *ppos)
00143 {
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 return 0;
00154 }
00155
00156 static int ccd_open(struct inode *inode, struct file *f){
00157 MOD_INC_USE_COUNT;
00158 opened++;
00159 f->f_pos=0;
00160 KDEBUG("Opened %d times\n",opened);
00161 return 0;
00162 }
00163
00164 static int ccd_release (struct inode *inode, struct file *f ){
00165 KDEBUG("release, still open:%d\n", opened-1);
00166 MOD_DEC_USE_COUNT;
00167 opened--;
00168 return 0;
00169 }
00170
00171 static int ccd_ioctl(struct inode *inode, struct file *f, unsigned int cmd, unsigned long arg){
00172 unsigned int cycles=arg/10;
00173 int pixelvalue;
00174
00175 switch(cmd){
00176 case CCD_CMD_GETPIXEL:
00177 pixelvalue = (int)CCD_PixWert(ccd_io);
00178 CCD_Next(ccd_io);
00179 CCD_Lesen(ccd_io);
00180 return pixelvalue;
00181
00182 case CCD_CMD_INITLESEN:
00183 CCD_Lesen(ccd_io);
00184 return 0;
00185
00186 case CCD_CMD_MONITORENABLE:
00187
00188 CCD_Monitoring(ccd_io);
00189 return 0;
00190
00191 case CCD_CMD_CLEAR:
00192 CCD_Monitoring(ccd_io);
00193 mysleep(6);
00194 CCD_Sammeln(ccd_io);
00195 mysleep(4);
00196 CCD_Move2Mem(ccd_io);
00197 return 0;
00198
00199 case CCD_CMD_EXPOSURE:
00200 if(cycles < 2) cycles = 2;
00201 CCD_Sammeln(ccd_io);
00202 mysleep(4);
00203 CCD_Move2Mem(ccd_io);
00204 CCD_Sammeln(ccd_io);
00205 mysleep(cycles);
00206 CCD_Move2Mem(ccd_io);
00207 CCD_Sammeln(ccd_io);
00208 mysleep(4);
00209 CCD_Move2Mem(ccd_io);
00210 CCD_Sammeln(ccd_io);
00211 return 0;
00212
00213 default:
00214 return -1;
00215 }
00216 return 0;
00217 }
00218
00219
00220
00221
00222 int ccd_initialize(){
00223 opened=0;
00224
00225 ccd_io = &ccd_parport_io;
00226
00227 KDEBUG_L1("Driver %s\n", CCD_VERSION);
00228
00229 ccd_io->base = LPT3_BASE;
00230 ccd_io->basehi = ccd_io->base + 0x400;
00231 KDEBUG("iobase: 0x%03x\n", (int)ccd_io->base);
00232
00233 ccd_io->save_status = inw_p(PARP_DATA(ccd_io));
00234 ccd_io->save_mode = inb_p(PARP_CONTROL(ccd_io));
00235 ccd_io->save_ecmode = inb_p(PARP_ECPCONTROL(ccd_io));
00236
00237 outw_p(0xffff, PARP_DATA(ccd_io));
00238 outb_p(0x20, PARP_ECPCONTROL(ccd_io));
00239
00240
00241 CCD_Monitoring(ccd_io);
00242
00243 KDEBUG("Init CCD module OK.\n");
00244
00245 return 0;
00246 }
00247
00248 inline void ccd_quit(){
00249
00250 CCD_Monitoring(ccd_io);
00251
00252
00253 outw_p(ccd_io->save_status, PARP_DATA(ccd_io));
00254 outb_p(ccd_io->save_mode, PARP_CONTROL(ccd_io));
00255 outb_p(ccd_io->save_ecmode, PARP_ECPCONTROL(ccd_io));
00256
00257 KDEBUG("CCD Driver deinstalled\n");
00258 }
00259
00260
00261
00262
00263
00264 struct file_operations ccd_fops = {
00265
00266 read: ccd_read,
00267
00268
00269
00270 ioctl: ccd_ioctl,
00271
00272 open: ccd_open,
00273
00274 release: ccd_release,
00275
00276
00277
00278
00279
00280 };
00281
00282 int init_module(void){
00283 KDEBUG("init_module CCD\n");
00284
00285 if ( devfs_register_chrdev (CCD_MAJOR, CCD_DEVICE_NAME, &ccd_fops) ){
00286 KDEBUG("unable create devfs entry for ccd device: %s, major: %d\n", CCD_DEVICE_NAME, CCD_MAJOR);
00287 return -EIO;
00288 }
00289 KDEBUG("Major number :%i \n", CCD_MAJOR);
00290
00291 devfs_handle = devfs_mk_dir (NULL, CCD_DEVFS_DIR, NULL);
00292
00293 devfs_register (devfs_handle, CCD_DEVICE_NAME,
00294 DEVFS_FL_DEFAULT, CCD_MAJOR, 0,
00295 S_IFCHR | S_IRUGO | S_IWUGO,
00296 &ccd_fops, NULL);
00297
00298 if(ccd_initialize())
00299 return -1;
00300
00301 return 0;
00302 }
00303
00304 void cleanup_module(void){
00305 KDEBUG("Module CCD unregistered\n");
00306 ccd_quit();
00307
00308 devfs_unregister (devfs_handle);
00309 devfs_unregister_chrdev(CCD_MAJOR, CCD_DEVICE_NAME);
00310
00311 KDEBUG("cleanup_module\n");
00312 }
00313
00314