/* fii-dt-driver.c - The simplest kernel module. * Copyright (C) 2013 - 2016 Xilinx, Inc * * This program is free software; you can redistribute it and/or modify * it unde r the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include #include #include #include #include #include #include /* for put_user */ #include #include #include /* Standard module information, edit as appropriate */ MODULE_LICENSE("GPL"); MODULE_AUTHOR ("FII inc."); MODULE_DESCRIPTION ("fii-dt-driver - loadable module template generated by petalinux-create -t modules"); #define DRIVER_NAME "fii-dt-driver" static const struct of_device_id of_match_fii_dt_driver[] = { // {.compatible = "fii,fii-dt-driver", .data = NULL}, {.compatible = "fii,fii-dt-driver", }, {/*sentinel*/}, }; static struct class *fii_dt_driver_class; static unsigned int major; static unsigned int * gpio_base; static unsigned int * gpio_data; static unsigned int * gpio_dir; static int fii_dt_driver_init(void); static int fii_dt_driver_open(struct inode* node,struct file* filp){ gpio_data = ioremap(gpio_base, 8); if(gpio_data){ printk("kernel: ioremap(0x%08x)=0x%08x \n", gpio_base, gpio_data); } else{ return -EINVAL; } gpio_dir = gpio_data + 1; return 0; } static int fii_dt_driver_release(struct platform_device * dev) { iounmap(gpio_data); unregister_chrdev(major, "fii-dt-driver"); device_destroy(fii_dt_driver_class,MKDEV(major,0)); class_destroy(fii_dt_driver_class); return 0; } static ssize_t fii_dt_driver_read(struct file *filp, char *buf, size_t size, loff_t *offset) { unsigned char val[32]; unsigned int temp; unsigned int *addr_p; int i,cnt; printk("kernel: fii-dt-driver read start.... size = %d\n", size); cnt = size; addr_p = gpio_data; temp = *addr_p ; for(i = 0; i < cnt/4; i++ ) { val[i*4 + 3] = temp & 0xff; val[i*4 + 2] = (temp >> 8) & 0xff; val[i*4 + 1] = (temp >> 16) & 0xff; val[i*4 + 0] = (temp >> 24) & 0xff; addr_p ++; temp = *addr_p; } if(i % 4 == 1) { val[i*4 + 0] = temp & 0xff; } if(i % 4 == 2) { val[i*4 + 1] = temp & 0xff; val[i*4 + 0] = (temp >> 8) & 0xff; } if(i % 4 == 3) { val[i*4 + 2] = temp & 0xff; val[i*4 + 1] = (temp >> 8) & 0xff; val[i*4 + 0] = (temp >> 16) & 0xff; } copy_to_user(buf, val, cnt); return cnt; } static ssize_t fii_dt_driver_write(struct file * filp, const char __user *buf, size_t size, loff_t * offset) { unsigned char val[32]; unsigned int temp = 0; unsigned int * addr_p; int i,cnt; memset(val,0,32); addr_p = gpio_data; printk("kernel: fii-dt-driver write start.... size = %d\n", size); copy_from_user(&val, buf, size); cnt = size - 1; printk("kernel: val[0] = 0x%08x \n", val[0]); if(val[0] == 'w') { temp = val[2]; temp = temp << 8 | val[3]; temp = temp << 8 | val[4]; temp = temp << 8 | val[5]; *addr_p = temp; printk("kernel: gpio_data = 0x%08x \n", temp); } else if(val[0] == 'd') { addr_p ++; temp = val[2]; temp = temp << 8 | val[3]; temp = temp << 8 | val[4]; temp = temp << 8 | val[5]; *addr_p = temp; printk("kernel: gpio_dir = 0x%08x \n", temp); } else { printk("kernel: invalid parameter \n"); } return size; } static struct file_operations fii_dt_driver_oprs = { .owner = THIS_MODULE, .open = fii_dt_driver_open, .write = fii_dt_driver_write, .read = fii_dt_driver_read, }; static int fii_dt_driver_probe(struct platform_device *pdev) { struct resource *res; printk ("kernel: enter fii_dt_driver probe ...... \n"); printk ("kernel: enter fii_dt_driver probe ...... \n"); printk ("kernel: enter fii_dt_driver probe ...... \n"); printk ("kernel: enter fii_dt_driver probe ...... \n"); printk ("kernel: enter fii_dt_driver probe ...... \n"); printk ("kernel: enter fii_dt_driver probe ...... \n"); res = platform_get_resource(pdev, IORESOURCE_MEM,0); if(res){ gpio_base = res->start; } major=register_chrdev(0, "fii-dt-driver", &fii_dt_driver_oprs); if (major < 0) { printk ("Registering the character device failed with %d\n", major); return major; } fii_dt_driver_class = class_create(THIS_MODULE, "fii-dt-driver_class"); device_create(fii_dt_driver_class,NULL,MKDEV(major,0),NULL,"fii-dt-driver"); return 0; } MODULE_DEVICE_TABLE(of, of_match_fii_dt_driver); static struct platform_driver fii_dt_driver_drv = { .driver = { .name = "fii-dt-driver", .owner = THIS_MODULE, .of_match_table = of_match_fii_dt_driver, }, .probe = fii_dt_driver_probe, .remove = fii_dt_driver_release, }; static int fii_dt_driver_init(void){ /* register device */ printk(KERN_ERR "|||||||||||||||||||||||||||||||||||||||||||||||| \r\n"); printk(KERN_ERR "|||||||||||||||||||||||||||||||||||||||||||||||| \r\n"); printk(KERN_ERR "|||||||||||||||||||||||||||||||||||||||||||||||| \r\n"); printk(KERN_ERR "\r\n"); // ############################################# // OF FUNCTIONS THAT FIND NODES TEST CODE INSERT // ############################################# printk(KERN_ERR "\r\n"); printk(KERN_ERR "################################################ \r\n"); printk(KERN_ERR "\r\n"); // ########################################################## // OF FUNCTIONS THAT FIND PARENT/CHILD NODES TEST CODE INSERT // ########################################################## printk(KERN_ERR "\r\n"); printk(KERN_ERR "################################################ \r\n"); printk(KERN_ERR "\r\n"); // ########################################################## // OF FUNCTIONS THAT EXTRACT PROPERTY VALUES TEST CODE INSERT // ########################################################## printk(KERN_ERR "\r\n"); printk(KERN_ERR "################################################ \r\n"); printk(KERN_ERR "\r\n"); // ########################################## // OTHER COMMON OF FUNCTIONS TEST CODE INSERT // ########################################## printk(KERN_ERR "\r\n"); printk(KERN_ERR "||||||||||||||||||||||||||||||||||||||||||||| \r\n"); printk(KERN_ERR "||||||||||||||||||||||||||||||||||||||||||||| \r\n"); printk(KERN_ERR "||||||||||||||||||||||||||||||||||||||||||||| \r\n"); return platform_driver_register(&fii_dt_driver_drv); } static void fii_dt_driver_exit(void){ platform_driver_unregister(&fii_dt_driver_drv); return; }; module_init(fii_dt_driver_init); module_exit(fii_dt_driver_exit); MODULE_ALIAS("platform:fii-dt-driver");