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流驱动替换

转载于:https://www.cnblogs.com/heimi/archive/2012/12/11/2812534.html

猜你喜欢

转载自blog.csdn.net/weixin_33874713/article/details/94565736