移植android13 nfc代码的时候,发现nfc vpad这个gpio 电一直拉不起来,而nxp的代码里又没有配置pinctrl片段。
//初始化,匹配dts里的pinctrl
static int nfc_pinctrl_init(struct device *dev,struct nfc_dev *nfc_dev)
{
int ret=0;
nfc_dev->pinctrl_data.pinctrl = devm_pinctrl_get(dev);
if (IS_ERR(nfc_dev->pinctrl_data.pinctrl)) {
ret = PTR_ERR(nfc_dev->pinctrl_data.pinctrl);
goto out;
}
nfc_dev->pinctrl_data.active =
pinctrl_lookup_state(nfc_dev->pinctrl_data.pinctrl,"nfc_active");
if (IS_ERR(nfc_dev->pinctrl_data.active)) {
ret = PTR_ERR(nfc_dev->pinctrl_data.active);
goto out;
}
nfc_dev->pinctrl_data.suspend =
pinctrl_lookup_state(nfc_dev->pinctrl_data.pinctrl, "nfc_suspend");
if (IS_ERR(nfc_dev->pinctrl_data.suspend)) {
ret = PTR_ERR(nfc_dev->pinctrl_data.suspend);
goto out;
}
out:
return ret;
}
//在probe阶段调用上面的函数
r = nfc_pinctrl_init(&client->dev, nfc_dev);
//配置pinctrl结构体
struct nfc_pinctrl_info {
struct pinctrl *pinctrl;
struct pinctrl_state *active;
struct pinctrl_state *suspend;
};
//在nfc的结构体里加上pinctrl结构体
struct nfc_dev {
struct nfc_pinctrl_info pinctrl_data;
}
//pinctrl配置enable disable的函数
static int nfc_set_pinctrl_state(struct nfc_dev *nfc_dev, bool enable)
{
int rc = 0;
struct pinctrl_state *state;
if (enable)
state = nfc_dev->pinctrl_data.active;
else
state = nfc_dev->pinctrl_data.suspend;
rc = pinctrl_select_state(nfc_dev->pinctrl_data.pinctrl, state);
if (rc)
printk("failed to set nfc pin state, rc=%d\n", rc);
return rc;
}
//调用
rc = nfc_set_pinctrl_state(nfc_dev, true);
patch:
diff --git a/drivers/nfc/nfc.c b/drivers/nfc/nfc.c
index 3a532a80..0e3c4ab5 100644
--- a/drivers/nfc/nfc.c
+++ b/drivers/nfc/nfc.c
@@ -62,6 +62,53 @@
#define platform_func(prefix, postfix) prefix##postfix
#define func(prefix, postfix) platform_func(prefix, postfix)
+
+static int nfc_set_pinctrl_state(struct nfc_dev *nfc_dev, bool enable)
+{
+ int rc = 0;
+ struct pinctrl_state *state;
+
+ if (enable)
+ state = nfc_dev->pinctrl_data.active;
+ else
+ state = nfc_dev->pinctrl_data.suspend;
+
+ rc = pinctrl_select_state(nfc_dev->pinctrl_data.pinctrl, state);
+ if (rc)
+ printk("failed to set nfc pin state, rc=%d\n", rc);
+
+ return rc;
+}
+
+static int nfc_pinctrl_init(struct device *dev,struct nfc_dev *nfc_dev)
+{
+ int ret=0;
+
+ nfc_dev->pinctrl_data.pinctrl = devm_pinctrl_get(dev);
+ if (IS_ERR(nfc_dev->pinctrl_data.pinctrl)) {
+ ret = PTR_ERR(nfc_dev->pinctrl_data.pinctrl);
+ goto out;
+ }
+
+ nfc_dev->pinctrl_data.active =
+ pinctrl_lookup_state(nfc_dev->pinctrl_data.pinctrl,"nfc_active");
+
+ if (IS_ERR(nfc_dev->pinctrl_data.active)) {
+ ret = PTR_ERR(nfc_dev->pinctrl_data.active);
+ goto out;
+ }
+
+ nfc_dev->pinctrl_data.suspend =
+ pinctrl_lookup_state(nfc_dev->pinctrl_data.pinctrl, "nfc_suspend");
+
+ if (IS_ERR(nfc_dev->pinctrl_data.suspend)) {
+ ret = PTR_ERR(nfc_dev->pinctrl_data.suspend);
+ goto out;
+ }
+out:
+ return ret;
+}
@@ -581,6 +633,18 @@ static int nfc_probe(struct i2c_client *client,
ret = -ENOMEM;
goto err_mem;
}
+
+ ret = nfc_pinctrl_init(&client->dev, nfc_dev);
+
+ ret = nfc_set_pinctrl_state(nfc_dev, true);
if (gpio_is_valid(platform_data.vpad_gpio)) {
ret = gpio_request(platform_data.vpad_gpio, "nfc_vpad_gpio");
@@ -589,12 +653,14 @@ static int nfc_probe(struct i2c_client *client,
__func__, platform_data.vpad_gpio);
goto err_mem;
}
+ pr_err("before platform_data.vpad_gpio test value : %d \n",gpio_get_value(platform_data.vpad_gpio));
ret = gpio_direction_output(platform_data.vpad_gpio, 1);
if (ret) {
pr_err("%s: unable to set direction for nfc vpad gpio [%d]\n",
__func__, platform_data.vpad_gpio);
goto err_vpad_gpio;
}
+ pr_err("after platform_data.vpad_gpio test value : %d \n",gpio_get_value(platform_data.vpad_gpio));
} else {
pr_err("%s: nfc vpad gpio not provided\n", __func__);
goto err_mem;
@@ -607,12 +673,14 @@ static int nfc_probe(struct i2c_client *client,
__func__, platform_data.ven_gpio);
goto err_mem;
}
+ pr_err("before platform_data.ven_gpio test value : %d \n",gpio_get_value(platform_data.ven_gpio));
ret = gpio_direction_output(platform_data.ven_gpio, 0);
if (ret) {
pr_err("%s: unable to set direction for nfc reset gpio [%d]\n",
__func__, platform_data.ven_gpio);
goto err_en_gpio;
}
+ pr_err("after platform_data.ven_gpio test value : %d \n",gpio_get_value(platform_data.ven_gpio));
} else {
pr_err("%s: nfc reset gpio not provided\n", __func__);
goto err_mem;
diff --git a/drivers/nfc/nfc.h b/drivers/nfc/nfc.h
index 0aac86f3..ebdf8f28 100644
--- a/drivers/nfc/nfc.h
+++ b/drivers/nfc/nfc.h
@@ -34,6 +34,12 @@
#define _NXP_NFC_H_
#define NXP_NFC_MAGIC 0xE9
+struct nfc_pinctrl_info {
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *active;
+ struct pinctrl_state *suspend;
+};
+
/* Device specific structure */
struct nfc_dev {
wait_queue_head_t read_wq;
@@ -53,6 +59,7 @@ struct nfc_dev {
unsigned int fw_major;
unsigned int fw_minor;
+ struct nfc_pinctrl_info pinctrl_data;
/* NFC_IRQ state */
bool irq_enabled;
spinlock_t irq_enabled_lock;