linux配置GPIO的方式
linux配置GPIO的方式
Kernel阶段的控制
1 使用Pinctrl框架控制
(1) 设备树文件相关节点
sn7326_power_pin {
qcom,pins = <&gp 3>;
qcom,num-grp-pins = <1>;
qcom,pin-func = <0>;
label ="sn7326-power-pin";
sn7326_power_active:sn7326_power_active {
drive-strength =<6>;
bias-pull-up;
output-high;
};
sn7326_power_sleep:sn7326_power_sleep {
drive-strength =<2>;
bias-pull-down;
output-low;
};
};
sn@58 {
compatible= "sn,sn7326";
reg= <0x58>;
pinctrl-names ="active","sleep";
pinctrl-0 = <&sn7326_power_active>;
pinctrl-1 =<&sn7326_power_sleep>;
interrupt-parent= <&msm_gpio>;
interrupts= <98 0x02>;
…
sn7326,pwr-en-gpio=<&msm_gpio 3 0x00>;//GPIO控制方式
};
(2) Pinctrl控制代码
static int sn7326_pinctrl_init(structsn7326_chip_data *data)
{
struct i2c_client *client = data->client;
data->pinctrl = devm_pinctrl_get(&client->dev);
if (IS_ERR_OR_NULL(data->pinctrl)) {
dev_err(&client->dev,"Failed to get pinctrl\n");
returnPTR_ERR(data->pinctrl);
}
data->pin_active =
pinctrl_lookup_state(data->pinctrl, "active");
if (IS_ERR_OR_NULL(data->pin_active)) {
dev_err(&client->dev,"Failed to look up default state\n");
returnPTR_ERR(data->pin_active);
}
data->pin_sleep =
pinctrl_lookup_state(data->pinctrl, "sleep");
if (IS_ERR_OR_NULL(data->pin_sleep)) {
dev_err(&client->dev,"Failed to look up sleep state\n");
returnPTR_ERR(data->pin_sleep);
}
return 0;
}
ret =pinctrl_select_state(chip_data->pinctrl, chip_data->pin_active);
if (ret) {
dev_err(&client->dev,
"Can't selectpinctrl default state\n");
goto free_pdata;
}
这里的chip_data->pin_active指向sn7326_power_active。
2 使用GPIO控制
(1) 设备树相关节点
sn@58 {
compatible= "sn,sn7326";
reg= <0x58>;
…
sn7326,pwr-en-gpio=<&msm_gpio 3 0x00>;//GPIO控制方式
};
(2) 代码控制
static int sn7326_kpd_parse_dt(structdevice *dev,struct sn7326_pdata *pdata)
{
intret = 0;
structdevice_node *np = dev->of_node;
pdata->pwr_en_gpio= of_get_named_gpio_flags(np, "sn7326,pwr-en-gpio",0, NULL);
if(gpio_is_valid(pdata->pwr_en_gpio)){
ret= gpio_request(pdata->pwr_en_gpio, "sn7326_pwr_en");
if(ret){
dev_err(dev,"%s: pwr-en gpio request failed.\n", __func__);
goto free_rst;
}
gpio_direction_output(pdata->pwr_en_gpio, 1);
}
pdata->irq_gpio= of_get_named_gpio_flags(np, "sn7326,interrupt-gpio",0, NULL);
if(!gpio_is_valid(pdata->irq_gpio)) {
gotofree_pwr_en;
}
returnret;
free_pwr_en:
if(gpio_is_valid(pdata->pwr_en_gpio))
gpio_free(pdata->pwr_en_gpio);
returnret;
}