zoukankan      html  css  js  c++  java
  • Regulator相关GPIO控制使用流程简析


    转载请注明出处,亲
    1,注册到平台 举例:
    extern struct gpio_regulator_platform_data v210_gpio_regs_platform_data;
    static struct platform_device v210_gpio_regulators_dev = {
        .name        = "gpio-regulators",
        .id        = -1,
        .dev = { .platform_data = &v210_gpio_regs_platform_data },
    };

    2,注册设备初始化接口

    static struct regulator_consumer_supply gpio_reg_gpa07_consumers[] = {
        {
            .supply        = "vdd_gps",
        },
    };
    static struct regulator_init_data gpio_reg_gpa07 = {
        .constraints    = {
            .name        = "VDD_GPS12/VDD_GPS28",
            .valid_ops_mask = REGULATOR_CHANGE_STATUS,
            .state_mem    = {
                .mode    = REGULATOR_MODE_NORMAL,
                .enabled = 0,
            },
        },
        .num_consumer_supplies    = ARRAY_SIZE(gpio_reg_gpa07_consumers),
        .consumer_supplies    = gpio_reg_gpa07_consumers,
    };
    
    static struct regulator_consumer_supply gpio_reg_gpb3_consumers[] = {
        {
            .supply        = "vdd_camb",
        },
    };
    static struct gpio_regulator v210_gpio_regulators [] = {
        [0] = {  /*"VDD_GPS",*/
            .gpio =  S5PV210_GPA0(7),
            .name = "LDO_GPA0(7)",
            .type = GPIO_REGULATOR_VOLTAGE,
            .initdata = &gpio_reg_gpa07,
        },
        [1] = { /*"VDD_CAMA",*/
            .gpio =  S5PV210_GPB(0),
            .name = "LDO_GPB(0)",
            .type = GPIO_REGULATOR_VOLTAGE,
            .initdata = &gpio_reg_gpb0,
        },
        [2] = { /*"VDD_CAMB",*/
            .gpio =  S5PV210_GPB(3),
            .name = "LDO_GPB(3)",
            .type = GPIO_REGULATOR_VOLTAGE,
            .initdata = &gpio_reg_gpb3,
        }
    。。。。。
    。。。。。
    }; struct gpio_regulator_platform_data v210_gpio_regs_platform_data = { .num_regulators = ARRAY_SIZE(v210_gpio_regulators), .regulators = v210_gpio_regulators, };

    3,Regulator设备驱动加载的时候初始化,下面的驱动的一般流程和LINUX下的流驱动   字符设备等基本没区别

    #include <linux/module.h>
    #include <linux/err.h>
    #include <linux/platform_device.h>
    #include <linux/regulator/driver.h>
    #include <linux/mutex.h>
    #include <linux/gpio.h>
    #include <plat/gpio-cfg.h>
    
    #include <plat/gpio_regulator.h>
    #include <linux/slab.h>
    
    struct gpio_regulator_device_data {
        struct device        *dev;
    
        struct gpio_regulator_platform_data *pdata;
    
        int    num_regulators;
        struct regulator_dev    **rdev;
        struct XXX_gpio_regulator_data *pregdata;
    };
    
    
    struct XXX_gpio_regulator_data{
        struct regulator_desc reg_desc;
        int gpio_pin;
        int active_low;
        enum gpio_pull_mode pull;
        int gpio_sleep;    /*sleep mode. */
    };
    
    static int XXX_gpio_reg_is_enabled(struct regulator_dev *rdev)
    {
        struct gpio_regulator_device_data *pddata = rdev_get_drvdata(rdev);
        struct XXX_gpio_regulator_data *pregdata;
        int id, ret;
        
        id = rdev_get_id(rdev);
        pregdata = &pddata->pregdata[id];
        
        ret = (gpio_get_value(pregdata->gpio_pin))?1:0;
        if(pregdata->active_low)
            ret = !ret;
        
        printk("XXX_gpio_reg_is_enabled, regulator:[%s] is %d\n", pregdata->reg_desc.name, ret);
        printk("gpio_pin: 0x%0x\n", pregdata->gpio_pin);
        
        return ret;
    }
    
    static int XXX_gpio_reg_enable(struct regulator_dev *rdev)
    {
        struct gpio_regulator_device_data *pddata = rdev_get_drvdata(rdev);
        struct XXX_gpio_regulator_data *pregdata;
        int id, value, ret;
    
        id = rdev_get_id(rdev);
        pregdata = &pddata->pregdata[id];
    
        printk("XXX_gpio_reg_enable, regulator: %s\n", pregdata->reg_desc.name);
        printk("gpio_pin: 0x%0x\n", pregdata->gpio_pin);
        
        s3c_gpio_cfgpin(pregdata->gpio_pin,S3C_GPIO_OUTPUT);
        s3c_gpio_setpull(pregdata->gpio_pin,((__force s3c_gpio_pull_t)pregdata->pull));
        gpio_set_value(pregdata->gpio_pin, (pregdata->active_low?0:1));
            
        return 0;
    }
    
    static int XXX_gpio_reg_disable(struct regulator_dev *rdev)
    {
        struct gpio_regulator_device_data *pddata = rdev_get_drvdata(rdev);
        struct XXX_gpio_regulator_data *pregdata;
        int id, value, ret;
    
        id = rdev_get_id(rdev);
        pregdata = &pddata->pregdata[id];
        
        printk("XXX_gpio_reg_disable, regulator: %s\n", pregdata->reg_desc.name );
        printk("gpio_pin: 0x%0x\n", pregdata->gpio_pin);
        
        s3c_gpio_cfgpin(pregdata->gpio_pin,S3C_GPIO_OUTPUT);
        s3c_gpio_setpull(pregdata->gpio_pin,((__force s3c_gpio_pull_t)pregdata->pull));
        gpio_set_value(pregdata->gpio_pin, (pregdata->active_low?1:0));
        return 0;
    }
    
    static int XXX_gpio_reg_set_voltage(struct regulator_dev *rdev,
                    int min_uV, int max_uV)
    {
        
        return 0;
    }
    
    static int XXX_gpio_reg_get_voltage(struct regulator_dev *rdev)
    {
    
        return 0;
    }
    
    static int XXX_gpio_reg_suspend_enable(struct regulator_dev *rdev)
    {
    
        return 0;
    }
    
    static int XXX_gpio_reg_suspend_disable(struct regulator_dev *rdev)
    {
    
        return 0;
    }
    
    static int XXX_gpio_reg_set_suspend_voltage(struct regulator_dev *rdev, int uV)
    {
        return 0;
    }
    
    
    
    
    
    static struct regulator_ops XXX_gpio_reg_ops = {
        .list_voltage    = NULL, //XXX_gpio_reg_list_voltage,
        .is_enabled    = XXX_gpio_reg_is_enabled,
        .enable        = XXX_gpio_reg_enable,
        .disable    = XXX_gpio_reg_disable,
        .get_voltage    = XXX_gpio_reg_get_voltage,
        .set_voltage    = NULL,
        .set_suspend_enable    = XXX_gpio_reg_suspend_enable,
        .set_suspend_disable    = XXX_gpio_reg_suspend_disable,
        .set_suspend_voltage    = NULL,
    };
    
    static int __devinit XXX_gpio_regulators_probe(struct platform_device *pdev)
    {
        int i, error;
        int id, ret;
        
        //jeff,
        struct gpio_regulator_platform_data *pdata = pdev->dev.platform_data;
        struct gpio_regulator_device_data *ddata;
        struct regulator_desc *gpio_reg_desc;
        
        printk("XXX_gpio_regulators_probe\n");
        
        ddata = kzalloc(sizeof(struct gpio_regulator_device_data),GFP_KERNEL);
        if (!ddata)
            return -ENOMEM;
        ddata->rdev  = kzalloc(sizeof(struct regulator_dev *) * (pdata->num_regulators + 1), GFP_KERNEL);
        if (!ddata->rdev) {
            kfree(ddata);
            return -ENOMEM;
        }    
    
        ddata->pregdata = kzalloc(sizeof(struct XXX_gpio_regulator_data) * (pdata->num_regulators + 1), GFP_KERNEL);
        if (!ddata->pregdata) {
            kfree(ddata->rdev);
            kfree(ddata);
            return -ENOMEM;
        }
        
        ddata->num_regulators = pdata->num_regulators;
        for (i = 0; i < ddata->num_regulators; i++) {
            gpio_reg_desc = &(ddata->pregdata[i].reg_desc);
            gpio_reg_desc->id = i;
            gpio_reg_desc->name =  pdata->regulators[i].name;
            gpio_reg_desc->type = pdata->regulators[i].type;
            gpio_reg_desc->ops = &XXX_gpio_reg_ops;
            gpio_reg_desc->n_voltages = 1;
            gpio_reg_desc->owner    = THIS_MODULE,
    
            /*add regulator pin configure*/
            ddata->pregdata[i].gpio_pin = pdata->regulators[i].gpio;
            ddata->pregdata[i].active_low= pdata->regulators[i].active_low;
            ddata->pregdata[i].pull = pdata->regulators[i].pull;
               /**/
    
            ddata->rdev[i] = regulator_register(gpio_reg_desc,
                ddata->dev,pdata->regulators[i].initdata, ddata);
            ret = IS_ERR(ddata->rdev[i]);
            if (ret)
                printk("[gpio_regulator] regulator:\"%s\" init failed\n", gpio_reg_desc->name);    
            else
                printk("[gpio_regulator] regulator:\"%s\" init success\n", gpio_reg_desc->name);
        }
        
        return ret;
    }
    
    static int __devexit XXX_gpio_regulators_remove(struct platform_device *pdev)
    {
        printk("XXX_gpio_regulators_remove\n");
        return 0;
    }
    
    
    
    static struct platform_driver gpio_regulators_driver = {
        .probe        = XXX_gpio_regulators_probe,
        .remove        = __devexit_p(XXX_gpio_regulators_remove),
        .driver        = {
            .name    = "gpio-regulators",
            .owner    = THIS_MODULE,
    #if 0
            .pm    = &gpio_regulators_pm_ops,
    #endif
        }
    };
    
    static int __init XXX_gpio_regulator_init(void)
    {
        printk("XXX_gpio_regulator_init\n");
        return platform_driver_register(&gpio_regulators_driver);
    }
    
    
    static void __exit XXX_gpio_regulator_exit(void)
    {
        platform_driver_unregister(&gpio_regulators_driver);
    }
    subsys_initcall(XXX_gpio_regulator_init);
    //subsys_initcall_sync(XXX_gpio_regulator_init);
    module_exit(XXX_gpio_regulator_exit);
    
    MODULE_DESCRIPTION("XXX gpio controlled regulator driver");
    MODULE_AUTHOR("SSCR jeff ");
    MODULE_LICENSE("GPL");

    4,使用方式

    首先,

    static  struct regulator *xxx_reg; 定义一个regulator结构体指针;

    其次,

    xxx_reg = regulator_get(NULL, "vdd_gps");获取这个指针

    最后操作

    if (IS_ERR(xxx_reg)) {
    printk(KERN_ERR "failed to get resource %s\n", "xxx_reg");
    }else{
    regulator_enable(wifi_reg);//通过此来操作I/O控制I/O

    }

    好处是,方便LINUX各个驱动内部之间的控制。当然也可以用一般的GPIO流驱动替换

  • 相关阅读:
    深入浅出Vue.js(四) 整体流程
    深入浅出Vue.js(三) 模板编译
    实现strStr()--indexOf()方法
    Z字形变换
    最长回文子串
    删除数组中不符合条件的值
    整数反转
    寻找两个正序数组的中位数
    gorm 关系一对一,一对多,多对多查询
    gorm 如何对字段进行comment注释?
  • 原文地址:https://www.cnblogs.com/heimi/p/2812534.html
Copyright © 2011-2022 走看看