Advertisement
Guest User

Untitled

a guest
Apr 25th, 2015
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.86 KB | None | 0 0
  1. /*
  2.  * This is a demo Linux kernel module.
  3.  */
  4.  
  5. #include <linux/kernel.h>
  6. #include <linux/module.h>
  7. #include <linux/init.h>
  8. #include <linux/ioport.h>
  9. #include <linux/io.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/cdev.h>
  12. #include <linux/types.h>
  13. #include <linux/fs.h>
  14. #include <linux/device.h>
  15.  
  16. #include <asm/signal.h>
  17. #include <asm/siginfo.h>
  18. #include <asm/uaccess.h>
  19.  
  20. #include "efm32gg.h"
  21.  
  22. /*
  23.  * template_init - function to insert this module into kernel space
  24.  *
  25.  * This is the first of two exported functions to handle insert ga  ing this
  26.  * code into a running kernel
  27.  *
  28.  * Returns 0 if successfull, otherwise -1
  29.  */
  30.  
  31. #define DEV_NAME "gamepad"
  32.  
  33. struct resource *gpio_pc;
  34. struct resource *gpio_irq;
  35. int setup_GPIO();
  36. int setup_interrupts();
  37.  
  38. //static irqreturn_t gpio_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs);
  39.  
  40. static int gp_open(struct inode*, struct file*);
  41. static int gp_release(struct inode*, struct file*);
  42. static ssize_t gp_read(struct file*, char* __user, size_t, loff_t*);
  43. static int gp_fasync(int, struct file*, int);
  44.  
  45. uint32_t *err, *err_odd, *err_even, *handler;
  46.  
  47. void *ioremap;
  48. void *irq_remap;
  49.  
  50. static struct class *gp_class;
  51. static struct device *gp_device;
  52. dev_t dev; //device number
  53. struct cdev gp_cdev;
  54. struct fasync_struct *fasync;
  55. static int major;
  56.  
  57. static struct gamepad_dev{
  58.     struct gp_qset *data;
  59.     int quantum;
  60.     int qset;
  61.     unsigned long size;
  62.     unsigned int acces_key;
  63.     struct semaphore sem;
  64.    
  65. } gp_dev;
  66.  
  67.  
  68. struct file_operations gp_fops = {
  69.     .owner = THIS_MODULE,
  70.     .read = gp_read,
  71.     .open = gp_open,
  72.     .release = gp_release,
  73.     .fasync = gp_fasync,
  74. };
  75.  
  76. irqreturn_t gpio_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs)
  77. {
  78.     //printk("Handling GPIO interrupt..\n");
  79.     //clear interrupt flag
  80.     iowrite16(ioread16(irq_remap + GPIO_IF - GPIO_EXTIPSELL), irq_remap + GPIO_IFC - GPIO_EXTIPSELL);
  81.     uint16_t button_state = ioread16(ioremap + GPIO_PC_DIN);
  82.     //Send signal
  83.     if(fasync){
  84.         kill_fasync(&fasync, SIGIO, POLL_IN);
  85.     }
  86.     //printk("Button state: %i\n", button_state);
  87.     return IRQ_HANDLED;
  88. }
  89.  
  90. static int gp_fasync(int fd, struct file *filp, int mode)
  91. {
  92.     //printk("HERRO DIS IS FASYNC\n");
  93.     struct gamepad_dev *gp_dev = filp->private_data;
  94.  
  95.     return fasync_helper(fd, filp, mode, &fasync);
  96. }
  97.  
  98. //INIT gamepad
  99. static int __init gamepad_init(void)
  100. {
  101.     printk("Hello World, here is your module: %c speaking v18\n", DEV_NAME);
  102.  
  103.     int err_reg = alloc_chrdev_region(&dev, 0, 1, DEV_NAME);
  104.     printk("dev: %i\n",dev);
  105.  
  106.     //major = MAJOR(*dev);
  107.     if(!err_reg){
  108.         printk("CharDev reg successfull\n");
  109.     }else{
  110.         printk("Failed to register dev\n");
  111.         printk("err: %i\n",err_reg);
  112.         return err_reg;
  113.     }
  114.    
  115.     cdev_init(&gp_cdev, &gp_fops);
  116.     gp_cdev.owner = THIS_MODULE;
  117.     printk(KERN_NOTICE "gp_dev.cdev.owner: %i", *gp_cdev.owner);
  118.     int err_cdev = cdev_add(&gp_cdev, dev, 1);
  119.     if(err_cdev){
  120.         printk(KERN_NOTICE "Error %i adding dev%i", err_cdev, 0);
  121.     }else{
  122.         printk(KERN_NOTICE "cdev added successfully!\n");
  123.     }
  124.    
  125.     //Create device file
  126.     struct class *gp_class = class_create(THIS_MODULE, "gamepad-class");
  127.  
  128.     if(IS_ERR(gp_class)){
  129.         return -1;
  130.     }
  131.  
  132.     printk("Created classfile\n");
  133.     struct device *devkok = device_create(gp_class, NULL, dev, NULL, DEV_NAME);
  134.    
  135.     pr_err("%s:%d error code %d\n", __func__, __LINE__, PTR_ERR(devkok));
  136.  
  137.     int err_gpio = setup_GPIO();
  138.     int err_irq = setup_interrupts();
  139.     return 0;
  140. }
  141.  
  142. //Open gamepad
  143. static int gp_open(struct inode *inode, struct file *file)
  144. {
  145.     printk("Opening Gamepad driver..\n\n");
  146.     return 0;
  147. }
  148.  
  149. //Close gamepad    
  150. static int gp_release(struct inode* inode, struct file* file)
  151. {
  152.     printk("Closing Gamepad driver..\n\n");
  153.     return 0;
  154. }
  155.  
  156. //GPIO setup
  157. int setup_GPIO(void)
  158. {
  159.     gpio_pc = request_mem_region(GPIO_PC_BASE, 36, DEV_NAME);
  160.    
  161.     if (IS_ERR(gpio_pc)){
  162.         printk("Failure\n");
  163.         return -1;
  164.     }
  165.     else{
  166.         printk("GPIO INPUT SUCCESS\n");
  167.     }
  168.  
  169.     //ioremap = GPIO_PC_BASE;
  170.     ioremap = ioremap_nocache(GPIO_PC_BASE, 36);
  171.     if(IS_ERR(ioremap)){return -1;}
  172.    
  173.     iowrite32(0x33333333, ioremap + GPIO_PC_MODEL);
  174.     printk("Set pin 0-7 for input...\n");
  175.     printk("MODEL: %i\n", ioread32(ioremap + GPIO_PC_MODEL));
  176.     //GPIO_PC_MODEL = 0x33333333;
  177.     iowrite32(0xff, ioremap + GPIO_PC_DOUT);
  178.     printk("Enable internal pull-up...\n");
  179.     //GPIO_PC_DOUT = 0xFF;
  180.  
  181.     printk("GPIO ARE NOW SET UP!\n\n");
  182.     //GPIO_IEN = 0xFF;
  183.     return 0;
  184. }
  185.  
  186.  
  187. int setup_interrupts(void)
  188. {
  189.     gpio_irq = request_mem_region(GPIO_PC_BASE + GPIO_EXTIPSELL, 32, DEV_NAME);
  190.    
  191.     if (IS_ERR(gpio_irq)){
  192.         printk("Failure\n");
  193.         return -1;
  194.     }
  195.     else{
  196.         printk("IRQ MEM REQUEST SUCCESS\n");
  197.     }
  198.  
  199.     //ioremap = GPIO_PC_BASE;
  200.     irq_remap = ioremap_nocache(GPIO_PA_BASE + GPIO_EXTIPSELL, 32);
  201.     if(IS_ERR(irq_remap)){return -1;}
  202.  
  203.     //GPIO_EXTIPSELL = 0x22222222;
  204.     iowrite32(0x22222222, irq_remap);
  205.     printk("Enable port C to handle the interrupt...\n%i\n", ioread32(irq_remap));
  206.  
  207.     //GPIO_EXTIFALL = 0xFF;
  208.     iowrite32(0xff,  irq_remap + GPIO_EXTIFALL - GPIO_EXTIPSELL);
  209.     printk("Set interrupt handling for 1->0 transitions...\n%i\n", ioread32(irq_remap + GPIO_EXTIFALL - GPIO_EXTIPSELL));
  210.  
  211.     //GPIO_EXTIRISE = 0xFF;
  212.     iowrite32(0xff,  irq_remap + GPIO_EXTIRISE - GPIO_EXTIPSELL);
  213.     printk("Set interrupt handling for 0->1 transitions...\n%i\n", ioread32(irq_remap + GPIO_EXTIRISE - GPIO_EXTIPSELL));
  214.  
  215.     //request GPIO_EVEN IRQ line (nr17)
  216.     err_even = request_irq(17, (irq_handler_t)gpio_interrupt_handler, 0, DEV_NAME, &gp_cdev);
  217.     if(err_even){
  218.         printk(KERN_INFO "can't get assigned irq 17\n");
  219.     }
  220.  
  221.     //request GPIO_ODD IRQ line (nr18)
  222.     err_odd = request_irq(18, (irq_handler_t)gpio_interrupt_handler, 0, DEV_NAME, &gp_cdev);
  223.     if(err_odd){
  224.         printk(KERN_INFO "can't get assigned irq 18\n");
  225.     }
  226.  
  227.     //GPIO_IEN = 0xFF;
  228.     iowrite32(0xff,  irq_remap + GPIO_IEN - GPIO_EXTIPSELL);
  229.     printk("Enable interrupt generation...\n%i\n", ioread32(irq_remap + GPIO_IEN - GPIO_EXTIPSELL));
  230.  
  231.     if(!err_even && !err_odd){
  232.         printk(KERN_INFO "GPIO INTERRUPTS ARE NOW SET UP!\n\n");
  233.         return 0;
  234.     }else{
  235.         return -1;
  236.     }
  237.    
  238. }
  239.  
  240.  
  241. static ssize_t gp_read(struct file* file, char* __user buff, size_t count, loff_t* loff_t)
  242. {
  243.     printk("Reading Gamepad..\n");
  244.     uint16_t val = ioread16(ioremap + GPIO_PC_DIN);
  245.     printk("Val = %i\n", val);
  246.     int cp_err = copy_to_user(buff, &val, count);
  247.     if(cp_err){
  248.         return cp_err;
  249.         printk(KERN_INFO "cp_err: %i\n", cp_err);
  250.     }else{
  251.         return count;
  252.     }
  253. }
  254.  
  255.  
  256. /*
  257.  * template_cleanup - function to cleanup this module from kernel space
  258.  *
  259.  * This is the second of two exported functions to handle cleanup this
  260.  * code from a running kernel
  261.  */
  262.  
  263. static void __exit gamepad_cleanup(void)
  264. {
  265.     unregister_chrdev_region(0,1);
  266.     release_mem_region(ioremap, 36);
  267.     printk("Short life for a small module...\n");
  268. }
  269.  
  270.  
  271. module_init(gamepad_init);
  272. module_exit(gamepad_cleanup);
  273.  
  274. MODULE_DESCRIPTION("Small module, demo only, not very useful.");
  275. MODULE_LICENSE("GPL");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement