/* 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 // ############################################# // of_find_node_by_name struct device_node *test_ofnbn; test_ofnbn = of_find_node_by_name(NULL, "test_node2"); if(NULL == &test_ofnbn){ printk(KERN_ERR "Node was not found via of_find_node_by_name \r\n"); } if(NULL != &test_ofnbn){ printk(KERN_ERR "Node was successfully found via of_find_node_by_name \r\n"); printk(KERN_ERR "Node name is: %s \r\n", test_ofnbn->name); } printk(KERN_ERR "\r\n"); // of_find_node_by_type struct device_node *test_ofnbt; test_ofnbt = of_find_node_by_type(NULL, "test_device_type1"); if(NULL == &test_ofnbt){ printk(KERN_ERR "Node was not found via of_find_node_by_type \r\n"); } if(NULL != &test_ofnbt){ printk(KERN_ERR "Node was successfully found via of_find_node_by_type \r\n"); printk(KERN_ERR "Node name is: %s \r\n", test_ofnbt->name); } printk(KERN_ERR "\r\n"); // of_find_compatible_node struct device_node *test_ofcndn; test_ofcndn = of_find_compatible_node(NULL, "test_device_type1", "fii,fii-dt-driver"); if(NULL == &test_ofcndn){ printk(KERN_ERR "Node was not found via of_find_compatible_node \r\n"); } if(NULL != &test_ofcndn){ printk(KERN_ERR "Node was successfully found via of_find_compatible_node \r\n"); printk(KERN_ERR "Node name is: %s \r\n", test_ofcndn->name); } printk(KERN_ERR "\r\n"); // of_find_matching_node_and_match const struct of_device_id *test_np; struct device_node *test_dn; test_dn = of_find_matching_node_and_match(NULL, of_match_fii_dt_driver, &test_np); if(NULL == &test_dn){ printk(KERN_ERR "Node was not found via of_find_matching_node_and_match \r\n"); } if(NULL != &test_dn){ printk(KERN_ERR "Node was successfully found via of_find_matching_node_and_match \r\n"); printk(KERN_ERR "Node name is: %s \r\n", test_dn->name); } printk(KERN_ERR "\r\n"); // of_find_node_by_path struct device_node *test_ofnbp; test_ofnbp = of_find_node_by_path("/test_node1"); if(NULL == &test_ofnbp){ printk(KERN_ERR "Node was not found via of_find_node_by_path \r\n"); } if(NULL != &test_ofnbp){ printk(KERN_ERR "Node was successfully found via of_find_node_by_path \r\n"); printk(KERN_ERR "Node name is: %s \r\n", test_ofnbp->name); } 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 // ########################################################## // of_get_parent struct device_node *test_ogp; test_ogp = of_get_parent(of_find_node_by_name(NULL, "test_node2")); if(NULL == &test_ogp){ printk(KERN_ERR "Parent node of test_node2 was not found via of_get_parent \r\n"); } if(NULL != &test_ogp){ printk(KERN_ERR "Parent node of test_node2 was successfully found via of_get_parent \r\n"); printk(KERN_ERR "Node name is: %s \r\n", test_ogp->name); } printk(KERN_ERR "\r\n"); // of_get_next_child struct device_node *test_ognc; test_ognc = of_get_next_child(of_find_node_by_name(NULL, "test_node1"), NULL); if(NULL == &test_ognc){ printk(KERN_ERR "Next child node of test_node1 was not found via of_get_next_child \r\n"); } if(NULL != &test_ognc){ printk(KERN_ERR "Next child node of test_node1 was successfully found via of_get_next_child \r\n"); printk(KERN_ERR "Node name is: %s \r\n", test_ognc->name); } printk(KERN_ERR "\r\n"); printk(KERN_ERR "################################################ \r\n"); printk(KERN_ERR "\r\n"); // ########################################################## // OF FUNCTIONS THAT EXTRACT PROPERTY VALUES TEST CODE INSERT // ########################################################## // of_find_property int plen; struct property *test_ofp; test_ofp = of_find_property(of_find_node_by_name(NULL, "test_node1"), "compatible", &plen); printk(KERN_ERR "Compatible property of test_node1 was successfully found via of_find_property \r\n"); printk(KERN_ERR "Property name is: %s \r\n", test_ofp->name); printk(KERN_ERR "\r\n"); // of_property_count_elems_of_size int test_opceos; const char propname[] = "reg"; printk(KERN_ERR "propname = %d \r\n" , sizeof(propname)); test_opceos = of_property_count_elems_of_size(of_find_node_by_name(NULL, "fii-dt-driver"),"compatible", 1); printk(KERN_ERR "Compatible property of test_node1 was successfully found via of_property_count_elems_of_size \r\n"); printk(KERN_ERR "Property element count is: %d \r\n", test_opceos); printk(KERN_ERR "\r\n"); // of_property_read_u32_index u32 oprui_output; int ret = 0; ret = of_property_read_u32_index(of_find_node_by_name(NULL, "test_node1"), "test_array", 0,&oprui_output); printk(KERN_ERR "test_array of test_node1 was successfully found via of_property_read_u32_index \r\n"); printk(KERN_ERR "Property value at index 0 is: ret = %d, 0x%08x\r\n", ret, oprui_output); printk(KERN_ERR "\r\n"); ret = of_property_read_u32_index(of_find_node_by_name(NULL, "test_node1"), "test_array", 1,&oprui_output); printk(KERN_ERR "Property value at index 1 is: ret = %d, 0x%08x\r\n", ret, oprui_output); printk(KERN_ERR "\r\n"); ret = of_property_read_u32_index(of_find_node_by_name(NULL, "test_node1"), "test_array", 2,&oprui_output); printk(KERN_ERR "Property value at index 2 is: ret = %d, 0x%08x\r\n", ret, oprui_output); printk(KERN_ERR "\r\n"); ret = of_property_read_u32_index(of_find_node_by_name(NULL, "test_node1"), "test_array", 3,&oprui_output); printk(KERN_ERR "Property value at index 3 is: ret = %d, 0x%08x\r\n", ret, oprui_output); printk(KERN_ERR "\r\n"); ret = of_property_read_u32_index(of_find_node_by_name(NULL, "test_node1"), "test_array", 4,&oprui_output); printk(KERN_ERR "Property value at index 4 is: ret = %d, 0x%08x\r\n", ret, oprui_output); printk(KERN_ERR "\r\n"); printk(KERN_ERR "\r\n"); printk(KERN_ERR "---------------------------------------------------- \r\n"); printk(KERN_ERR "\r\n"); // of_property_read_u_array size_t elements; int i; // of_property_read_u8_array u8 test_opru8a_out[5]; int test_opru8a; elements = 5; test_opru8a = of_property_read_u8_array(of_find_node_by_name(NULL, "test_node1"),"test_array", test_opru8a_out, elements); printk(KERN_ERR "test_array of test_node1 was successfully found via of_property_read_u8_array \r\n"); for(i = 0; i < elements; i++){ printk(KERN_ERR "Return value : %d \nProperty value is: 0x%02x\r\n", test_opru8a,test_opru8a_out[i]); } printk(KERN_ERR "\r\n"); elements = 5; test_opru8a = of_property_read_u8_array(of_find_node_by_name(NULL, "test_node2"),"u8_test_array", test_opru8a_out, elements); printk(KERN_ERR "u8_test_array of test_node2 was successfully found via of_property_read_u8_array \r\n"); for(i = 0; i < elements; i++){ printk(KERN_ERR "Return value : %d \nProperty value is: 0x%02x\r\n", test_opru8a,test_opru8a_out[i]); } printk(KERN_ERR "\r\n"); // of_property_read_u16_array u16 test_opru16a_out[5]; int test_opru16a; elements = 5; test_opru16a = of_property_read_u16_array(of_find_node_by_name(NULL, "test_node1"),"test_array", test_opru16a_out, elements); printk(KERN_ERR "test_array of test_node1 was successfully found via of_property_read_u16_array \r\n"); for(i = 0; i < elements; i++){ printk(KERN_ERR "Return value : %d \nProperty value is: 0x%04x\r\n", test_opru16a,test_opru16a_out[i]); } printk(KERN_ERR "\r\n"); elements = 5; test_opru16a = of_property_read_u16_array(of_find_node_by_name(NULL, "test_node2"),"u16_test_array", test_opru16a_out, elements); printk(KERN_ERR "u16_test_array of test_node2 was successfully found via of_property_read_u16_array \r\n"); for(i = 0; i < elements; i++){ printk(KERN_ERR "Return value : %d \nProperty value is: 0x%04x\r\n", test_opru16a,test_opru16a_out[i]); } printk(KERN_ERR "\r\n"); // of_property_read_u32_array u32 test_opru32a_out[5]; int test_opru32a; elements = 5; test_opru32a = of_property_read_u32_array(of_find_node_by_name(NULL, "test_node2"),"u32_test_array", test_opru32a_out, elements); printk(KERN_ERR "u32_test_array of test_node2 was successfully found via of_property_read_u32_array \r\n"); for(i = 0; i < elements; i++){ printk(KERN_ERR "Return value : %d \nProperty value is: 0x%06x\r\n", test_opru32a,test_opru32a_out[i]); } printk(KERN_ERR "\r\n"); // of_property_read_u64_array u64 test_opru64a_out[5]; int test_opru64a; elements = 5; test_opru64a = of_property_read_u64_array(of_find_node_by_name(NULL, "test_node2"),"u64_test_array", test_opru64a_out, elements); printk(KERN_ERR "u64_test_array of test_node2 was successfully found via of_property_read_u64_array \r\n"); for(i = 0; i < elements; i++){ printk(KERN_ERR "Return value : %d \nProperty value is: 0x%08x\r\n", test_opru64a,test_opru64a_out[i]); } printk(KERN_ERR "\r\n"); printk(KERN_ERR "\r\n"); printk(KERN_ERR "---------------------------------------------------- \r\n"); printk(KERN_ERR "\r\n"); // of_property_read_u8 u8 test_opru8_out; int test_opru8; test_opru8 = of_property_read_u8(of_find_node_by_name(NULL, "test_node2"), "u8_test_array",&test_opru8_out); printk(KERN_ERR "u8_test_array of test_node2 was successfully found via of_property_read_u8 \r\n"); printk(KERN_ERR "Return value : %d \nProperty value is: 0x%02x\r\n", test_opru8,test_opru8_out); printk(KERN_ERR "\r\n"); test_opru8 = of_property_read_u8(of_find_node_by_name(NULL, "test_node2"), "u8_test",&test_opru8_out); printk(KERN_ERR "u8_test of test_node2 was successfully found via of_property_read_u8 \r\n"); printk(KERN_ERR "Return value : %d \nProperty value is: 0x%02x\r\n", test_opru8,test_opru8_out); printk(KERN_ERR "\r\n"); // of_property_read_u16 u16 test_opru16_out; int test_opru16; test_opru16 = of_property_read_u16(of_find_node_by_name(NULL, "test_node2"),"u16_test_array", &test_opru16_out); printk(KERN_ERR "u16_test_array of test_node2 was successfully found via of_property_read_u16 \r\n"); printk(KERN_ERR "Return value : %d \nProperty value is: 0x%04x\r\n", test_opru16,test_opru16_out); printk(KERN_ERR "\r\n"); test_opru16 = of_property_read_u16(of_find_node_by_name(NULL, "test_node2"), "u16_test",&test_opru16_out); printk(KERN_ERR "u16_test of test_node2 was successfully found via of_property_read_u16 \r\n"); printk(KERN_ERR "Return value : %d \nProperty value is: 0x%04x\r\n", test_opru16,test_opru16_out); printk(KERN_ERR "\r\n"); // of_property_read_u32 u32 test_opru32_out; int test_opru32; test_opru32 = of_property_read_u32(of_find_node_by_name(NULL, "test_node2"),"u32_test_array", &test_opru32_out); printk(KERN_ERR "u32_test_array of test_node2 was successfully found via of_property_read_u32 \r\n"); printk(KERN_ERR "Return value : %d \nProperty value is: 0x%06x\r\n", test_opru32,test_opru32_out); printk(KERN_ERR "\r\n"); test_opru32 = of_property_read_u32(of_find_node_by_name(NULL, "test_node2"), "u32_test",&test_opru32_out); printk(KERN_ERR "u32_test of test_node2 was successfully found via of_property_read_u32 \r\n"); printk(KERN_ERR "Return value : %d \nProperty value is: 0x%06x\r\n", test_opru32,test_opru32_out); printk(KERN_ERR "\r\n"); // of_property_read_u64 u64 test_opru64_out; int test_opru64; test_opru64 = of_property_read_u64(of_find_node_by_name(NULL, "test_node2"),"u64_test_array", &test_opru64_out); printk(KERN_ERR "u64_test_array of test_node2 was successfully found via of_property_read_u64 \r\n"); printk(KERN_ERR "Return value : %d \nProperty value is: 0x%08x\r\n", test_opru64,test_opru64_out); printk(KERN_ERR "\r\n"); test_opru64 = of_property_read_u64(of_find_node_by_name(NULL, "test_node2"), "u64_test",&test_opru64_out); printk(KERN_ERR "u64_test of test_node2 was successfully found via of_property_read_u64 \r\n"); printk(KERN_ERR "Return value : %d \nProperty value is: 0x%08x\r\n", test_opru64,test_opru64_out); printk(KERN_ERR "\r\n"); printk(KERN_ERR "---------------------------------------------------- \r\n"); printk(KERN_ERR "\r\n"); // of_property_read_string const char *test_oprs_out; int test_oprs; test_oprs = of_property_read_string(of_find_node_by_name(NULL, "test_node1"), "status",&test_oprs_out); printk(KERN_ERR "status was successfully found via of_property_read_string \r\n"); printk(KERN_ERR "Return value : %d \nProperty value is: %s\r\n", test_oprs, test_oprs_out); printk(KERN_ERR "\r\n"); // of_n_addr_cells int test_onac; test_onac = of_n_addr_cells(of_find_node_by_name(NULL, "fii-dt-driver")); printk(KERN_ERR "Address Cells was successfully found via of_n_addr_cells \r\n"); printk(KERN_ERR "Return value : %d\n", test_onac); printk(KERN_ERR "\r\n"); // of_n_size_cells int test_onsc; test_onsc = of_n_size_cells(of_find_node_by_name(NULL, "fii-dt-driver")); printk(KERN_ERR "Size Cells was successfully found via of_n_size_cells \r\n"); printk(KERN_ERR "Return value : %d\n", test_onsc); printk(KERN_ERR "\r\n"); printk(KERN_ERR "################################################ \r\n"); printk(KERN_ERR "\r\n"); // ########################################## // OTHER COMMON OF FUNCTIONS TEST CODE INSERT // ########################################## // of_device_is_compatible int test_odic; test_odic = of_device_is_compatible(of_find_node_by_name(NULL, "fii-dt-driver"), "fii,fii-dt-driver"); printk(KERN_ERR "Compatible was successfully found via of_device_is_compatible \r\n"); printk(KERN_ERR "Return value : %d\n", test_odic); printk(KERN_ERR "\r\n"); // of_get_address const __be32 *test_oga; u64 test_oga_size; test_oga = of_get_address(of_find_node_by_name(NULL, "fii-dt-driver"), 0, &test_oga_size,NULL); printk(KERN_ERR "Address was successfully found via of_get_address \r\n"); printk(KERN_ERR "Return value : 0x%08x\n", test_oga); printk(KERN_ERR "\r\n"); // of_translate_address u64 test_ota; test_ota = of_translate_address(of_find_node_by_name(NULL, "fii-dt-driver"), test_oga); printk(KERN_ERR "Address was successfully translated via of_translate_address \r\n"); printk(KERN_ERR "Return value : 0x%08x\n", test_ota); printk(KERN_ERR "\r\n"); // of_address_to_resource int test_oatr; struct resource res; test_oatr = of_address_to_resource(of_find_node_by_name(NULL, "fii-dt-driver"), 0, &res); printk(KERN_ERR "Resource was successfully transfered via of_address_to_resource \n"); printk(KERN_ERR "Return value: %d \nProperty value is: 0x%08x\n", test_oatr, res); printk(KERN_ERR "\r\n"); // of_iomap void __iomem *test_oi; test_oi = of_iomap(of_find_node_by_name(NULL, "fii-dt-driver"), 0); printk(KERN_ERR "Mapping was successful via of_iomap \n"); printk(KERN_ERR "Return value: 0x%08x\n", test_oi); 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");