linux配置GPIO的方式
1. Bootloader阶段的控制
\bootable\bootloader\lk\platform\msm8909\gpio.c
/* configure rx gpio */ gpio_tlmm_config(21,3, GPIO_INPUT, GPIO_NO_PULL, GPIO_8MA,GPIO_DISABLE);
这里的21是指GPIO_21,3表示function配置项,普通GPIO对应0,如下图:
图1
2. Kernel阶段的控制
2.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。
(3)
2.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; }