1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/types.h>
4 #include <linux/kernel.h>
6 #include <linux/cdev.h>
7 #include <linux/sched.h>
8 #include <asm/current.h>
9 #include <asm/uaccess.h>
13 #include <linux/ioport.h>
15 #include <linux/interrupt.h>
16 #include <linux/fcntl.h>
17 #include <linux/slab.h>
21 MODULE_LICENSE("GPL");
23 #define DRIVER_NAME "kmjpeg"
26 #define AHBADD 0xa0000000
27 #define RDYADD 0xa0000200
28 #define APBADD 0x80000c00
31 /* Physical address for NEEK
32 #define AHBADD 0xb0000000
33 #define RDYADD 0xb0000200
34 #define APBADD 0x80000700
37 static struct kmjpeg_priv *kmjpeg_devices;
39 static unsigned int kmjpeg_major = 0;
40 module_param(kmjpeg_major, uint, 0);
42 struct kmjpeg_sregs_t {
43 volatile unsigned int fbadd;
44 volatile unsigned int size_info;
45 volatile unsigned int inc_add;
46 volatile unsigned int reset;
49 struct kmjpeg_sregs_t * kmjpeg_sregs;
51 //volatile unsigned int *apb_regs;
53 volatile unsigned int *hdata;
54 volatile unsigned int *rdyadd;
56 int kmjpeg_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
60 struct ioctl_cmdreg datareg;
61 struct ioctl_cmdwrite datawrite;
66 memset(&datareg, 0, sizeof(datareg));
67 memset(&datawrite, 0, sizeof(datawrite));
74 if(!access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd))){
78 if(copy_from_user(&datawrite, (int __user *)arg, sizeof(datawrite))){
85 if((tmp & 0x80000000) == 0x80000000)break;
88 // *hdata = datawrite.pixeldata;
90 *hdata = datawrite.fourbdata[i];
95 // printk("IOCTL_REGSET\n");
96 if(!access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd))){
98 printk("ACCESS_NG\n");
101 // printk("end of access_ok\n");
102 if(copy_from_user(&datareg, (int __user *)arg, sizeof(datareg))){
107 // printk("IOCTL regset ..............................\n");
108 kmjpeg_sregs = ioremap_nocache(APBADD,12);
109 // printk("IOCTL regset2 ..............................\n");
110 kmjpeg_sregs->fbadd = datareg.fb;
111 kmjpeg_sregs->size_info = datareg.size_info;
112 kmjpeg_sregs->inc_add = datareg.inc_add;
113 kmjpeg_sregs->reset = 0x0;
114 kmjpeg_sregs->reset =0xffffffff;
115 iounmap(kmjpeg_sregs);
116 // printk("IOCTL regset3 ..............................\n");
128 ssize_t kmjpeg_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
132 unsigned char dbuf[3];
138 if(copy_from_user(dbuf, buf, 3)){
142 ycc = (unsigned int)(((unsigned int)dbuf[2]<<16)|((unsigned int)dbuf[1]<<8)|((unsigned int)dbuf[0]));
149 static ssize_t kmjpeg_read(struct file* pFile, char __user* pBuf, size_t len, loff_t* offset)
157 static int kmjpeg_open(struct inode *inode, struct file *file)
160 printk("%s: major %d minor %d (pid %d)\n", __func__,imajor(inode),iminor(inode),current->pid);
162 inode->i_private = inode;
163 file->private_data = file;
164 printk(" i_private=%p private_data=%p\n",inode->i_private, file->private_data);
165 // printk("kmjpeg_open ending\n");
169 static int kmjpeg_close(struct inode *inode, struct file *file)
171 printk("%s: major %d minor %d (pid %d)\n", __func__,imajor(inode),iminor(inode),current->pid);
172 printk(" i_private=%p private_data=%p\n",inode->i_private, file->private_data);
177 struct file_operations kmjpeg_fops ={
178 .owner = THIS_MODULE,
180 .release = kmjpeg_close,
182 .write = kmjpeg_write,
183 .ioctl = kmjpeg_ioctl,
186 static int kmjpeg_init(void)
191 major = register_chrdev(kmjpeg_major, DRIVER_NAME, &kmjpeg_fops);
193 if((kmjpeg_major > 0 && major != 0) || (kmjpeg_major == 0 && major < 0) || major < 0){
194 printk("%s driver registration error\n", DRIVER_NAME);
198 if (kmjpeg_major == 0){
199 kmjpeg_major = major;
202 hdata = ioremap_nocache(AHBADD,4);
204 printk("ioremap miss!\n");
207 rdyadd = ioremap_nocache(RDYADD,4);
209 printk("ioremap miss!\n");
212 printk("%s driver[major %d] installed.\n", DRIVER_NAME, kmjpeg_major);
218 static void kmjpeg_exit(void)
222 // kfree(kmjpeg_devices);
224 unregister_chrdev(kmjpeg_major, DRIVER_NAME);
225 printk("%s driver unloaded\n", DRIVER_NAME);
228 module_init(kmjpeg_init);
229 module_exit(kmjpeg_exit);