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