Regulator関連GPIO制御使用フローの概要

23615 ワード



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 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 

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
", pregdata->reg_desc.name, ret); printk("gpio_pin: 0x%0x
", 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
", pregdata->reg_desc.name); printk("gpio_pin: 0x%0x
", 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
", pregdata->reg_desc.name ); printk("gpio_pin: 0x%0x
", 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
"); 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
", gpio_reg_desc->name); else printk("[gpio_regulator] regulator:\"%s\" init success
", gpio_reg_desc->name); } return ret; } static int __devexit XXX_gpio_regulators_remove(struct platform_device *pdev) { printk("XXX_gpio_regulators_remove
"); 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
"); 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", "xxx_reg"); }else{regulator_enable(wifi_reg);//I/O制御I/Oを操作する
}
利点は,LINUXの各駆動内部間の制御を容易にすることである.もちろん一般的なGPIOフロー駆動で置き換えることもできます
 
 
 
転載先:https://www.cnblogs.com/heimi/archive/2012/12/11/2812534.html