Quantcast
Channel: Active questions tagged linux-kernel - Stack Overflow
Viewing all articles
Browse latest Browse all 12244

How to configure MIO47 as GPIO using pinmux in AVNET ZYNQ7000?

$
0
0

How to configure MIO47 as GPIO using pinmux in AVNET ZYNQ7000?

I have written a simple gpio sysfs based driver to control certain pins.I understand that MIO47 is used for controlling the user LED based on this document -https://www.avnet.com/opasdata/d120001/medias/docus/4/Avnet-MicroZed-Getting-Started-EN-User-Guide.pdf

My question is that I doubt that the pin subystem hasn't configured the MIO47 to GPIO by default.How can I verify that? Is there any document that shows the default mode for MIO47.Also, how do I change programaticallyso that I can configure MIO47 as a GPIO pin?

Here is my code -

#include <linux/module.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/device.h>/** for copy_to_user and copy_from_user **/#include <linux/uaccess.h> /** For IS_ERR(), PTR_ERR(), and ERR_PTR() **/#include <linux/err.h>/** container_of **/#include<linux/kernel.h>/** kzalloc **/#include <linux/slab.h>#include <linux/platform_device.h>/**platform_device_id - match based out of platform_device_id **/#include <linux/mod_devicetable.h>#include <linux/of_device.h>/** for accessing gpios **/#include <linux/gpio/consumer.h>/**private static prototypes**///static int check_permission(fmode_t mode, int perm);/**Finally I will do kzalloc of this structure and save it in the driver field of platform device->dev-> structure*/struct gpiodev_private_data{   char label[20];   struct gpio_desc *desc;};struct gpiodrv_private_data {   int total_devices;   struct class *class_gpio;   struct device **dev_sysfs;};struct gpiodrv_private_data gpiodrv_data;/**Trick to get the function name **/#undef pr_fmt#define pr_fmt(fmt) "%s : "fmt,__func__struct of_device_id gpio_sysfs_dt_match[] = { { .compatible = "org,bone-gpio-sysfs" }, { } // NULL terminated};ssize_t direction_show(struct device *dev, struct device_attribute *attr, char *buf){   int direction;   char *dir;   struct gpiodev_private_data *dev_data = dev_get_drvdata(dev);   direction = gpiod_get_direction(dev_data->desc);   if( direction < 0) {      pr_err("Failed reading gpiod - direction\r\n");      return direction;   }   dir = direction? "in" : "out";   return sprintf(buf,"%s\n",dir);}ssize_t direction_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){   struct gpiodev_private_data *dev_data = dev_get_drvdata(dev);   if(sysfs_streq(buf,"in")) {      if(gpiod_direction_input(dev_data->desc)) {         pr_err("Failed to set the direction input \r\n");      }   }   else if(sysfs_streq(buf,"out")) {      if(gpiod_direction_output(dev_data->desc, 0)) {         pr_err("Failed to set the direction output\r\n");      }   }   else    return -EINVAL;   return count;}ssize_t value_show(struct device *dev, struct device_attribute *attr, char *buf){   struct gpiodev_private_data *dev_data = dev_get_drvdata(dev);   int value = gpiod_get_value(dev_data->desc);   return sprintf(buf,"%d\n", value);}ssize_t value_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){   struct gpiodev_private_data *dev_data = dev_get_drvdata(dev);   long val;   int ret;   ret = kstrtol(buf,0, &val);   if(ret)   {     pr_err("Incorrect value by the user\r\n");     return ret;   }   gpiod_set_value(dev_data->desc, val);   return count;}ssize_t label_show(struct device *dev, struct device_attribute *attr, char *buf){   struct gpiodev_private_data *dev_data = dev_get_drvdata(dev);   return sprintf(buf,"%s\n", dev_data->label);}static DEVICE_ATTR_RW(direction);static DEVICE_ATTR_RW(value);static DEVICE_ATTR_RO(label);static struct attribute *gpio_attrs[] = {&dev_attr_direction.attr,&dev_attr_value.attr,&dev_attr_label.attr,   NULL};static struct attribute_group gpio_group = {   .attrs = gpio_attrs};const struct attribute_group *gpio_attr_groups[] ={&gpio_group,   NULL};int gpio_sysfs_platform_driver_probe (struct platform_device *pDev){      struct device_node *parent = pDev->dev.of_node;   struct device_node *child;   struct gpiodev_private_data *dev_data;   struct device    *dev = &pDev->dev;   const char *name;   int i = 0;   int ret;   gpiodrv_data.total_devices = of_get_child_count(parent);   if(!gpiodrv_data.total_devices){      dev_err(dev, "Error - No devices found\r\n");      return -EINVAL;   }   dev_info(dev, "child count = %d\r\n", gpiodrv_data.total_devices);   gpiodrv_data.dev_sysfs = devm_kzalloc(&pDev->dev, sizeof(struct device *) * gpiodrv_data.total_devices, GFP_KERNEL);   for_each_available_child_of_node(parent, child)   {      dev_data = devm_kzalloc(dev, sizeof(struct gpiodev_private_data),GFP_KERNEL);      if(!dev_data)      {         pr_err("No memory \r\n");         return -ENOMEM;      }      if(of_property_read_string(child, "label", &name))      {         pr_err("Missing label \r\n");         snprintf(dev_data->label,sizeof(dev_data->label), "unknown-gpio-%d",i);      }      else      {         strcpy(dev_data->label, name);         dev_info(dev,"GPIO label = %s\n",dev_data->label);      }      dev_data->desc = devm_fwnode_get_gpiod_from_child(dev,"bone",&child->fwnode, GPIOD_ASIS, dev_data->label);      if(IS_ERR(dev_data->desc)) {         ret = PTR_ERR(dev_data->desc);         if(ret == -ENONET) {            dev_err(dev, "get gpiod failed - no entry found\r\n");         }         return ret;      }      /** gpio/gpio.txt **/      ret = gpiod_direction_output(dev_data->desc, 0);      if(ret) {         dev_err(dev,"Err setting gpio direction failed = %d\r\n",i);         return ret;      }      gpiodrv_data.dev_sysfs[i] = device_create_with_groups(gpiodrv_data.class_gpio, dev, 0, dev_data, gpio_attr_groups, dev_data->label);      if(IS_ERR(gpiodrv_data.dev_sysfs[i])) {         ret = PTR_ERR(gpiodrv_data.dev_sysfs[i]);         dev_err(dev, "Error creating device with groups \r\n");         return ret;      }      i++;   }   return 0;}int gpio_sysfs_driver_remove(struct platform_device *pDev){    int i = 0;   dev_info(&pDev->dev, "Removing gpio syfs driver\r\n");   for(i = 0; i < gpiodrv_data.total_devices; i++) {      device_unregister(gpiodrv_data.dev_sysfs[i]);      }   return 0;}struct platform_driver gpiosysfs_platform_driver = {    .probe =  gpio_sysfs_platform_driver_probe,    .remove = gpio_sysfs_driver_remove,    .driver = {          .name =  "bone-gpio-sysfs",          . of_match_table = of_match_ptr(gpio_sysfs_dt_match),    },  };/**Entry Point of the Kernel Module **//** Called when the module is inserted -insmod **/static int __init gpio_sysfs_init(void){   int ret;   gpiodrv_data.class_gpio = class_create(THIS_MODULE, "bone_gpios");   ret = platform_driver_register(&gpiosysfs_platform_driver);     return ret;  }/** Called when the module is removed - rmmod**/static void __exit gpio_sysfs_exit(void){   platform_driver_unregister(&gpiosysfs_platform_driver);   class_destroy(gpiodrv_data.class_gpio);   pr_info("module unloaded\n");}/**module registration **/module_init(gpio_sysfs_init);module_exit(gpio_sysfs_exit);/*GPL - check module.h - very important */MODULE_LICENSE("GPL"); MODULE_AUTHOR("SJ");MODULE_DESCRIPTION("GPIO Sysfs Driver - Device Tree based");MODULE_INFO(board, "MICROZED - AVNET");

Viewing all articles
Browse latest Browse all 12244

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>