Loading drivers/nfc/qti/nfc_common.c +134 −1 Original line number Diff line number Diff line Loading @@ -10,9 +10,10 @@ int nfc_parse_dt(struct device *dev, struct platform_gpio *nfc_gpio, uint8_t interface) struct platform_ldo *ldo, uint8_t interface) { struct device_node *np = dev->of_node; int ret; if (!np) { pr_err("nfc of_node NULL\n"); Loading Loading @@ -49,9 +50,139 @@ int nfc_parse_dt(struct device *dev, struct platform_gpio *nfc_gpio, pr_info("%s: ven %d, dwl req %d, clkreq %d\n", __func__, nfc_gpio->ven, nfc_gpio->dwl_req, nfc_gpio->clkreq); // optional property ret = of_property_read_u32_array(np, NFC_LDO_VOL_DT_NAME, (u32 *) ldo->vdd_levels, ARRAY_SIZE(ldo->vdd_levels)); if (ret) { dev_err(dev, "error reading NFC VDDIO min and max value\n"); // set default as per datasheet ldo->vdd_levels[0] = NFC_VDDIO_MIN; ldo->vdd_levels[1] = NFC_VDDIO_MAX; } // optional property ret = of_property_read_u32(np, NFC_LDO_CUR_DT_NAME, &ldo->max_current); if (ret) { dev_err(dev, "error reading NFC current value\n"); // set default as per datasheet ldo->max_current = NFC_CURRENT_MAX; } return 0; } /** * nfc_ldo_vote() * @nfc_dev: NFC device containing regulator handle * * LDO voting based on voltage and current entries in DT * * Return: 0 on success and -ve on failure */ int nfc_ldo_vote(struct nfc_dev *nfc_dev) { int ret; ret = regulator_set_voltage(nfc_dev->reg, nfc_dev->ldo.vdd_levels[0], nfc_dev->ldo.vdd_levels[1]); if (ret < 0) { pr_err("%s: set voltage failed\n", __func__); return ret; } /* pass expected current from NFC in uA */ ret = regulator_set_load(nfc_dev->reg, nfc_dev->ldo.max_current); if (ret < 0) { pr_err("%s: set load failed\n", __func__); return ret; } ret = regulator_enable(nfc_dev->reg); if (ret < 0) pr_err("%s: regulator_enable failed\n", __func__); else nfc_dev->is_vreg_enabled = true; return ret; } /** * nfc_ldo_config() * @dev: device instance to read DT entry * @nfc_dev: NFC device containing regulator handle * * Configure LDO if entry is present in DT file otherwise * return with success as it's optional * * Return: 0 on success and -ve on failure */ int nfc_ldo_config(struct device *dev, struct nfc_dev *nfc_dev) { int ret; if (of_get_property(dev->of_node, NFC_LDO_SUPPLY_NAME, NULL)) { // Get the regulator handle nfc_dev->reg = regulator_get(dev, NFC_LDO_SUPPLY_DT_NAME); if (IS_ERR(nfc_dev->reg)) { ret = PTR_ERR(nfc_dev->reg); nfc_dev->reg = NULL; pr_err("%s: regulator_get failed, ret = %d\n", __func__, ret); return ret; } } else { nfc_dev->reg = NULL; pr_err("%s: regulator entry not present\n", __func__); // return success as it's optional to configure LDO return 0; } // LDO config supported by platform DT ret = nfc_ldo_vote(nfc_dev); if (ret < 0) { pr_err("%s: LDO voting failed, ret = %d\n", __func__, ret); regulator_put(nfc_dev->reg); } return ret; } /** * nfc_ldo_unvote() * @nfc_dev: NFC device containing regulator handle * * set voltage and load to zero and disable regulator * * Return: 0 on success and -ve on failure */ int nfc_ldo_unvote(struct nfc_dev *nfc_dev) { int ret; if (!nfc_dev->is_vreg_enabled) { pr_err("%s: regulator already disabled\n", __func__); return -EINVAL; } ret = regulator_disable(nfc_dev->reg); if (ret < 0) { pr_err("%s: regulator_disable failed\n", __func__); return ret; } nfc_dev->is_vreg_enabled = false; ret = regulator_set_voltage(nfc_dev->reg, 0, NFC_VDDIO_MAX); if (ret < 0) { pr_err("%s: set voltage failed\n", __func__); return ret; } ret = regulator_set_load(nfc_dev->reg, 0); if (ret < 0) pr_err("%s: set load failed\n", __func__); return ret; } void gpio_set_ven(struct nfc_dev *nfc_dev, int value) { if (gpio_get_value(nfc_dev->gpio.ven) != value) { Loading Loading @@ -295,6 +426,7 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg) } else { pr_debug("ven already HIGH\n"); } nfc_dev->is_ese_session_active = true; } else if (arg == ESE_POWER_OFF) { if (!nfc_dev->nfc_ven_enabled) { pr_debug("NFC not enabled, disabling ven\n"); Loading @@ -302,6 +434,7 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg) } else { pr_debug("keep ven high as NFC is enabled\n"); } nfc_dev->is_ese_session_active = false; } else if (arg == ESE_COLD_RESET) { // set default value for status as failure Loading drivers/nfc/qti/nfc_common.h +24 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/uaccess.h> #include <linux/slab.h> #include <linux/nfcinfo.h> #include <linux/regulator/consumer.h> #include "nfc_i2c_drv.h" #include "nfc_i3c_drv.h" Loading Loading @@ -86,6 +87,15 @@ #define DTS_FWDN_GPIO_STR "qcom,sn-firm" #define DTS_CLKREQ_GPIO_STR "qcom,sn-clkreq" #define DTS_CLKSRC_GPIO_STR "qcom,clk-src" #define NFC_LDO_SUPPLY_DT_NAME "qcom,nq-vdd-1p8" #define NFC_LDO_SUPPLY_NAME "qcom,nq-vdd-1p8-supply" #define NFC_LDO_VOL_DT_NAME "qcom,nq-vdd-1p8-voltage" #define NFC_LDO_CUR_DT_NAME "qcom,nq-vdd-1p8-current" //as per SN1x0 datasheet #define NFC_VDDIO_MIN 1650000 //in uV #define NFC_VDDIO_MAX 1950000 //in uV #define NFC_CURRENT_MAX 157000 //in uA enum ese_ioctl_request { /* eSE POWER ON */ Loading Loading @@ -163,6 +173,12 @@ struct platform_gpio { unsigned int dwl_req; }; // NFC LDO entries from DT struct platform_ldo { int vdd_levels[2]; int max_current; }; //Features specific Parameters struct cold_reset { wait_queue_head_t read_wq; Loading @@ -186,12 +202,16 @@ struct nfc_dev { uint8_t interface; /* NFC VEN pin state */ bool nfc_ven_enabled; bool is_vreg_enabled; bool is_ese_session_active; union { struct i2c_dev i2c_dev; struct i3c_dev i3c_dev; }; struct platform_gpio gpio; struct platform_ldo ldo; struct cold_reset cold_reset; struct regulator *reg; /* read buffer*/ size_t kbuflen; Loading @@ -211,7 +231,7 @@ int nfc_dev_open(struct inode *inode, struct file *filp); int nfc_dev_close(struct inode *inode, struct file *filp); long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg); int nfc_parse_dt(struct device *dev, struct platform_gpio *nfc_gpio, uint8_t interface); struct platform_ldo *ldo, uint8_t interface); int nfc_misc_probe(struct nfc_dev *nfc_dev, const struct file_operations *nfc_fops, int count, char *devname, char *classname); Loading @@ -220,5 +240,8 @@ int configure_gpio(unsigned int gpio, int flag); void read_cold_reset_rsp(struct nfc_dev *nfc_dev, char *header); void gpio_set_ven(struct nfc_dev *nfc_dev, int value); int nfcc_hw_check(struct nfc_dev *nfc_dev); int nfc_ldo_config(struct device *dev, struct nfc_dev *nfc_dev); int nfc_ldo_vote(struct nfc_dev *nfc_dev); int nfc_ldo_unvote(struct nfc_dev *nfc_dev); #endif //_NFC_COMMON_H_ drivers/nfc/qti/nfc_i2c_drv.c +23 −1 Original line number Diff line number Diff line Loading @@ -256,12 +256,13 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) struct nfc_dev *nfc_dev = NULL; struct i2c_dev *i2c_dev = NULL; struct platform_gpio nfc_gpio; struct platform_ldo nfc_ldo; pr_debug("%s: enter\n", __func__); //retrieve details of gpios from dt ret = nfc_parse_dt(&client->dev, &nfc_gpio, PLATFORM_IF_I2C); ret = nfc_parse_dt(&client->dev, &nfc_gpio, &nfc_ldo, PLATFORM_IF_I2C); if (ret) { pr_err("%s : failed to parse dt\n", __func__); goto err; Loading Loading @@ -341,6 +342,12 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) i2c_disable_irq(nfc_dev); i2c_set_clientdata(client, nfc_dev); ret = nfc_ldo_config(&client->dev, nfc_dev); if (ret) { pr_err("LDO config failed\n"); goto err_ldo_config_failed; } ret = nfcc_hw_check(nfc_dev); if (ret) { pr_err("nfc hw check failed ret %d\n", ret); Loading @@ -349,11 +356,17 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) device_init_wakeup(&client->dev, true); i2c_dev->irq_wake_up = false; nfc_dev->is_ese_session_active = false; pr_info("%s success\n", __func__); return 0; err_nfcc_hw_check: if (nfc_dev->reg) { nfc_ldo_unvote(nfc_dev); regulator_put(nfc_dev->reg); } err_ldo_config_failed: free_irq(client->irq, nfc_dev); err_nfc_misc_remove: nfc_misc_remove(nfc_dev, DEV_COUNT); Loading Loading @@ -386,6 +399,15 @@ int nfc_i2c_dev_remove(struct i2c_client *client) ret = -ENODEV; return ret; } gpio_set_value(nfc_dev->gpio.ven, 0); // HW dependent delay before LDO goes into LPM mode usleep_range(10000, 10100); if (nfc_dev->reg) { nfc_ldo_unvote(nfc_dev); regulator_put(nfc_dev->reg); } device_init_wakeup(&client->dev, false); free_irq(client->irq, nfc_dev); nfc_misc_remove(nfc_dev, DEV_COUNT); Loading drivers/nfc/qti/nfc_i3c_drv.c +2 −1 Original line number Diff line number Diff line Loading @@ -584,12 +584,13 @@ int nfc_i3c_dev_probe(struct i3c_device *device) int ret = 0; struct nfc_dev *nfc_dev = NULL; struct platform_gpio nfc_gpio; struct platform_ldo nfc_ldo; pr_debug("%s: enter\n", __func__); //retrieve gpio details from dt ret = nfc_parse_dt(&device->dev, &nfc_gpio, PLATFORM_IF_I3C); ret = nfc_parse_dt(&device->dev, &nfc_gpio, &nfc_ldo, PLATFORM_IF_I3C); if (ret) { pr_err("%s : failed to parse nfc dt node\n", __func__); goto err; Loading Loading
drivers/nfc/qti/nfc_common.c +134 −1 Original line number Diff line number Diff line Loading @@ -10,9 +10,10 @@ int nfc_parse_dt(struct device *dev, struct platform_gpio *nfc_gpio, uint8_t interface) struct platform_ldo *ldo, uint8_t interface) { struct device_node *np = dev->of_node; int ret; if (!np) { pr_err("nfc of_node NULL\n"); Loading Loading @@ -49,9 +50,139 @@ int nfc_parse_dt(struct device *dev, struct platform_gpio *nfc_gpio, pr_info("%s: ven %d, dwl req %d, clkreq %d\n", __func__, nfc_gpio->ven, nfc_gpio->dwl_req, nfc_gpio->clkreq); // optional property ret = of_property_read_u32_array(np, NFC_LDO_VOL_DT_NAME, (u32 *) ldo->vdd_levels, ARRAY_SIZE(ldo->vdd_levels)); if (ret) { dev_err(dev, "error reading NFC VDDIO min and max value\n"); // set default as per datasheet ldo->vdd_levels[0] = NFC_VDDIO_MIN; ldo->vdd_levels[1] = NFC_VDDIO_MAX; } // optional property ret = of_property_read_u32(np, NFC_LDO_CUR_DT_NAME, &ldo->max_current); if (ret) { dev_err(dev, "error reading NFC current value\n"); // set default as per datasheet ldo->max_current = NFC_CURRENT_MAX; } return 0; } /** * nfc_ldo_vote() * @nfc_dev: NFC device containing regulator handle * * LDO voting based on voltage and current entries in DT * * Return: 0 on success and -ve on failure */ int nfc_ldo_vote(struct nfc_dev *nfc_dev) { int ret; ret = regulator_set_voltage(nfc_dev->reg, nfc_dev->ldo.vdd_levels[0], nfc_dev->ldo.vdd_levels[1]); if (ret < 0) { pr_err("%s: set voltage failed\n", __func__); return ret; } /* pass expected current from NFC in uA */ ret = regulator_set_load(nfc_dev->reg, nfc_dev->ldo.max_current); if (ret < 0) { pr_err("%s: set load failed\n", __func__); return ret; } ret = regulator_enable(nfc_dev->reg); if (ret < 0) pr_err("%s: regulator_enable failed\n", __func__); else nfc_dev->is_vreg_enabled = true; return ret; } /** * nfc_ldo_config() * @dev: device instance to read DT entry * @nfc_dev: NFC device containing regulator handle * * Configure LDO if entry is present in DT file otherwise * return with success as it's optional * * Return: 0 on success and -ve on failure */ int nfc_ldo_config(struct device *dev, struct nfc_dev *nfc_dev) { int ret; if (of_get_property(dev->of_node, NFC_LDO_SUPPLY_NAME, NULL)) { // Get the regulator handle nfc_dev->reg = regulator_get(dev, NFC_LDO_SUPPLY_DT_NAME); if (IS_ERR(nfc_dev->reg)) { ret = PTR_ERR(nfc_dev->reg); nfc_dev->reg = NULL; pr_err("%s: regulator_get failed, ret = %d\n", __func__, ret); return ret; } } else { nfc_dev->reg = NULL; pr_err("%s: regulator entry not present\n", __func__); // return success as it's optional to configure LDO return 0; } // LDO config supported by platform DT ret = nfc_ldo_vote(nfc_dev); if (ret < 0) { pr_err("%s: LDO voting failed, ret = %d\n", __func__, ret); regulator_put(nfc_dev->reg); } return ret; } /** * nfc_ldo_unvote() * @nfc_dev: NFC device containing regulator handle * * set voltage and load to zero and disable regulator * * Return: 0 on success and -ve on failure */ int nfc_ldo_unvote(struct nfc_dev *nfc_dev) { int ret; if (!nfc_dev->is_vreg_enabled) { pr_err("%s: regulator already disabled\n", __func__); return -EINVAL; } ret = regulator_disable(nfc_dev->reg); if (ret < 0) { pr_err("%s: regulator_disable failed\n", __func__); return ret; } nfc_dev->is_vreg_enabled = false; ret = regulator_set_voltage(nfc_dev->reg, 0, NFC_VDDIO_MAX); if (ret < 0) { pr_err("%s: set voltage failed\n", __func__); return ret; } ret = regulator_set_load(nfc_dev->reg, 0); if (ret < 0) pr_err("%s: set load failed\n", __func__); return ret; } void gpio_set_ven(struct nfc_dev *nfc_dev, int value) { if (gpio_get_value(nfc_dev->gpio.ven) != value) { Loading Loading @@ -295,6 +426,7 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg) } else { pr_debug("ven already HIGH\n"); } nfc_dev->is_ese_session_active = true; } else if (arg == ESE_POWER_OFF) { if (!nfc_dev->nfc_ven_enabled) { pr_debug("NFC not enabled, disabling ven\n"); Loading @@ -302,6 +434,7 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg) } else { pr_debug("keep ven high as NFC is enabled\n"); } nfc_dev->is_ese_session_active = false; } else if (arg == ESE_COLD_RESET) { // set default value for status as failure Loading
drivers/nfc/qti/nfc_common.h +24 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/uaccess.h> #include <linux/slab.h> #include <linux/nfcinfo.h> #include <linux/regulator/consumer.h> #include "nfc_i2c_drv.h" #include "nfc_i3c_drv.h" Loading Loading @@ -86,6 +87,15 @@ #define DTS_FWDN_GPIO_STR "qcom,sn-firm" #define DTS_CLKREQ_GPIO_STR "qcom,sn-clkreq" #define DTS_CLKSRC_GPIO_STR "qcom,clk-src" #define NFC_LDO_SUPPLY_DT_NAME "qcom,nq-vdd-1p8" #define NFC_LDO_SUPPLY_NAME "qcom,nq-vdd-1p8-supply" #define NFC_LDO_VOL_DT_NAME "qcom,nq-vdd-1p8-voltage" #define NFC_LDO_CUR_DT_NAME "qcom,nq-vdd-1p8-current" //as per SN1x0 datasheet #define NFC_VDDIO_MIN 1650000 //in uV #define NFC_VDDIO_MAX 1950000 //in uV #define NFC_CURRENT_MAX 157000 //in uA enum ese_ioctl_request { /* eSE POWER ON */ Loading Loading @@ -163,6 +173,12 @@ struct platform_gpio { unsigned int dwl_req; }; // NFC LDO entries from DT struct platform_ldo { int vdd_levels[2]; int max_current; }; //Features specific Parameters struct cold_reset { wait_queue_head_t read_wq; Loading @@ -186,12 +202,16 @@ struct nfc_dev { uint8_t interface; /* NFC VEN pin state */ bool nfc_ven_enabled; bool is_vreg_enabled; bool is_ese_session_active; union { struct i2c_dev i2c_dev; struct i3c_dev i3c_dev; }; struct platform_gpio gpio; struct platform_ldo ldo; struct cold_reset cold_reset; struct regulator *reg; /* read buffer*/ size_t kbuflen; Loading @@ -211,7 +231,7 @@ int nfc_dev_open(struct inode *inode, struct file *filp); int nfc_dev_close(struct inode *inode, struct file *filp); long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg); int nfc_parse_dt(struct device *dev, struct platform_gpio *nfc_gpio, uint8_t interface); struct platform_ldo *ldo, uint8_t interface); int nfc_misc_probe(struct nfc_dev *nfc_dev, const struct file_operations *nfc_fops, int count, char *devname, char *classname); Loading @@ -220,5 +240,8 @@ int configure_gpio(unsigned int gpio, int flag); void read_cold_reset_rsp(struct nfc_dev *nfc_dev, char *header); void gpio_set_ven(struct nfc_dev *nfc_dev, int value); int nfcc_hw_check(struct nfc_dev *nfc_dev); int nfc_ldo_config(struct device *dev, struct nfc_dev *nfc_dev); int nfc_ldo_vote(struct nfc_dev *nfc_dev); int nfc_ldo_unvote(struct nfc_dev *nfc_dev); #endif //_NFC_COMMON_H_
drivers/nfc/qti/nfc_i2c_drv.c +23 −1 Original line number Diff line number Diff line Loading @@ -256,12 +256,13 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) struct nfc_dev *nfc_dev = NULL; struct i2c_dev *i2c_dev = NULL; struct platform_gpio nfc_gpio; struct platform_ldo nfc_ldo; pr_debug("%s: enter\n", __func__); //retrieve details of gpios from dt ret = nfc_parse_dt(&client->dev, &nfc_gpio, PLATFORM_IF_I2C); ret = nfc_parse_dt(&client->dev, &nfc_gpio, &nfc_ldo, PLATFORM_IF_I2C); if (ret) { pr_err("%s : failed to parse dt\n", __func__); goto err; Loading Loading @@ -341,6 +342,12 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) i2c_disable_irq(nfc_dev); i2c_set_clientdata(client, nfc_dev); ret = nfc_ldo_config(&client->dev, nfc_dev); if (ret) { pr_err("LDO config failed\n"); goto err_ldo_config_failed; } ret = nfcc_hw_check(nfc_dev); if (ret) { pr_err("nfc hw check failed ret %d\n", ret); Loading @@ -349,11 +356,17 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) device_init_wakeup(&client->dev, true); i2c_dev->irq_wake_up = false; nfc_dev->is_ese_session_active = false; pr_info("%s success\n", __func__); return 0; err_nfcc_hw_check: if (nfc_dev->reg) { nfc_ldo_unvote(nfc_dev); regulator_put(nfc_dev->reg); } err_ldo_config_failed: free_irq(client->irq, nfc_dev); err_nfc_misc_remove: nfc_misc_remove(nfc_dev, DEV_COUNT); Loading Loading @@ -386,6 +399,15 @@ int nfc_i2c_dev_remove(struct i2c_client *client) ret = -ENODEV; return ret; } gpio_set_value(nfc_dev->gpio.ven, 0); // HW dependent delay before LDO goes into LPM mode usleep_range(10000, 10100); if (nfc_dev->reg) { nfc_ldo_unvote(nfc_dev); regulator_put(nfc_dev->reg); } device_init_wakeup(&client->dev, false); free_irq(client->irq, nfc_dev); nfc_misc_remove(nfc_dev, DEV_COUNT); Loading
drivers/nfc/qti/nfc_i3c_drv.c +2 −1 Original line number Diff line number Diff line Loading @@ -584,12 +584,13 @@ int nfc_i3c_dev_probe(struct i3c_device *device) int ret = 0; struct nfc_dev *nfc_dev = NULL; struct platform_gpio nfc_gpio; struct platform_ldo nfc_ldo; pr_debug("%s: enter\n", __func__); //retrieve gpio details from dt ret = nfc_parse_dt(&device->dev, &nfc_gpio, PLATFORM_IF_I3C); ret = nfc_parse_dt(&device->dev, &nfc_gpio, &nfc_ldo, PLATFORM_IF_I3C); if (ret) { pr_err("%s : failed to parse nfc dt node\n", __func__); goto err; Loading