nxp: Import oplus changes from CPH2723_15.0.2.501(EX01)
Change-Id: Iff8b173fccfc1465608a6ca96e00d36018fd29d3
This commit is contained in:
committed by
Bruno Martins
parent
a1309047cc
commit
ee4446fb99
@@ -19,3 +19,7 @@ nxp-nci-objs += nfc/ese_cold_reset.o \
|
||||
nfc/common_qcom.o \
|
||||
nfc/i2c_drv.o
|
||||
|
||||
#ifdef CONFIG_NXP_NFC_VBAT_MONITOR
|
||||
nxp-nci-objs += nfc/nfc_vbat_monitor.o
|
||||
ccflags-y += -DCONFIG_NXP_NFC_VBAT_MONITOR
|
||||
#endif
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export CONFIG_NXP_NFC_I2C=m
|
||||
export CONFIG_NXP_NFC_VBAT_MONITOR=m
|
||||
|
||||
@@ -9,3 +9,4 @@
|
||||
***************************************************************************/
|
||||
|
||||
#define CONFIG_NXP_NFC_I2C 1
|
||||
#define CONFIG_NXP_NFC_VBAT_MONITOR 1
|
||||
|
||||
@@ -23,8 +23,10 @@ def define_modules(target, variant):
|
||||
"nfc/common_qcom.c",
|
||||
"nfc/ese_cold_reset.c",
|
||||
"nfc/i2c_drv.c",
|
||||
"nfc/nfc_vbat_monitor.c",
|
||||
"nfc/common.h",
|
||||
"nfc/common_nxp.h",
|
||||
"nfc/nfc_vbat_monitor.h",
|
||||
"nfc/ese_cold_reset.h",
|
||||
"nfc/i2c_drv.h"
|
||||
],
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pinctrl/qcom-pinctrl.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include "common.h"
|
||||
bool secure_peripheral_not_found = true;
|
||||
|
||||
@@ -56,6 +57,17 @@ int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs,
|
||||
return nfc_gpio->irq;
|
||||
}
|
||||
pr_info("NxpDrv: %s: irq %d\n", __func__, nfc_gpio->irq);
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
nfc_gpio->vbat_irq = -EINVAL;
|
||||
nfc_gpio->vbat_irq =
|
||||
of_get_named_gpio(np, DTS_NFC_VBAT_MONITOR_STR, 0);
|
||||
if ((!gpio_is_valid(nfc_gpio->vbat_irq))) {
|
||||
pr_err("%s: vbat_irq gpio invalid %d\n", __func__,
|
||||
nfc_gpio->vbat_irq);
|
||||
//return nfc_gpio->vbat_irq;
|
||||
}
|
||||
pr_err("%s: vbat gpio %d\n", __func__, nfc_gpio->vbat_irq);
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
}
|
||||
nfc_gpio->ven = of_get_named_gpio(np, DTS_VEN_GPIO_STR, 0);
|
||||
if ((!gpio_is_valid(nfc_gpio->ven))) {
|
||||
@@ -217,6 +229,11 @@ void gpio_free_all(struct nfc_dev *nfc_dev)
|
||||
if (gpio_is_valid(nfc_gpio->irq))
|
||||
gpio_free(nfc_gpio->irq);
|
||||
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
if (gpio_is_valid(nfc_gpio->vbat_irq))
|
||||
gpio_free(nfc_gpio->vbat_irq);
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
|
||||
if (gpio_is_valid(nfc_gpio->ven))
|
||||
gpio_free(nfc_gpio->ven);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <nfcinfo.h>
|
||||
#include <sn_uapi.h>
|
||||
#include "i2c_drv.h"
|
||||
#include "nfc_vbat_monitor.h"
|
||||
#include "ese_cold_reset.h"
|
||||
|
||||
#ifdef NFC_SECURE_PERIPHERAL_ENABLED
|
||||
@@ -91,12 +92,16 @@
|
||||
#define MAX_RETRY_COUNT (3)
|
||||
#define MAX_WRITE_IRQ_COUNT (5)
|
||||
#define MAX_IRQ_WAIT_TIME (90)
|
||||
#define WAKEUP_SRC_TIMEOUT (100)
|
||||
#define WAKEUP_SRC_TIMEOUT (500)
|
||||
|
||||
/* command response timeout */
|
||||
#define NCI_CMD_RSP_TIMEOUT_MS (2000)
|
||||
/* Time to wait for NFCC to be ready again after any change in the GPIO */
|
||||
#define NFC_GPIO_SET_WAIT_TIME_US (10000)
|
||||
/* #ifdef OPLUS_BUG_STABILITY */
|
||||
/* #define NFC_GPIO_SET_WAIT_TIME_US (10000) */
|
||||
/* #else OPLUS_BUG_STABILITY */
|
||||
#define NFC_GPIO_SET_WAIT_TIME_US (20000)
|
||||
/* #endif OPLUS_BUG_STABILITY */
|
||||
/* Time to wait before retrying writes */
|
||||
#define WRITE_RETRY_WAIT_TIME_US (3000)
|
||||
/* Time to wait before retrying read for some specific usecases */
|
||||
@@ -226,6 +231,9 @@ enum gpio_values {
|
||||
/* NFC GPIO variables */
|
||||
struct platform_gpio {
|
||||
unsigned int irq;
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
unsigned int vbat_irq;
|
||||
//#endif CONFIG_NXP_NFC_VBAT_MONITOR
|
||||
unsigned int ven;
|
||||
unsigned int clkreq;
|
||||
unsigned int dwl_req;
|
||||
@@ -277,6 +285,9 @@ struct nfc_dev {
|
||||
};
|
||||
struct platform_configs configs;
|
||||
struct cold_reset cold_reset;
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
struct nfc_vbat_monitor nfc_vbat_monitor;
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
struct regulator *reg;
|
||||
|
||||
/* read buffer*/
|
||||
@@ -331,4 +342,9 @@ int validate_nfc_state_nci(struct nfc_dev *nfc_dev);
|
||||
int nfc_post_init(struct nfc_dev *nfc_dev);
|
||||
int nfc_dynamic_protection_ioctl(struct nfc_dev *nfc_dev, unsigned long sec_zone_trans);
|
||||
bool nfc_hw_secure_check(void);
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
int nfc_vbat_monitor_init(struct nfc_dev *nfc_dev,
|
||||
struct platform_gpio *nfc_gpio,
|
||||
struct i2c_client *client);
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
#endif /* _COMMON_H_ */
|
||||
|
||||
@@ -281,6 +281,7 @@ int nfcc_hw_check(struct nfc_dev *nfc_dev)
|
||||
struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio;
|
||||
|
||||
/*get fw version in nci mode*/
|
||||
usleep_range(NFC_GPIO_SET_WAIT_TIME_US,NFC_GPIO_SET_WAIT_TIME_US + 100);//add for Satisfy VEN spec of 15ms delay
|
||||
gpio_set_ven(nfc_dev, 1);
|
||||
gpio_set_ven(nfc_dev, 0);
|
||||
gpio_set_ven(nfc_dev, 1);
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#define DL_GET_SESSION_CMD_CRC_2 (0x33)
|
||||
#define GET_SESSION_STS_OFF (3)
|
||||
#define NFCC_SESSION_STS_CLOSED (0x0)
|
||||
#define NFC_GPIO_SET_WAIT_TIME_US (20000)
|
||||
|
||||
/* Below offsets should be subtracted from NCI header length + payload length */
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
#include <linux/compat.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
#include "nfc_vbat_monitor.h"
|
||||
//#endif CONFIG_NXP_NFC_VBAT_MONITOR
|
||||
|
||||
/**
|
||||
* i2c_disable_irq()
|
||||
@@ -152,6 +155,16 @@ int i2c_read(struct nfc_dev *nfc_dev, char *buf, size_t count, int timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
if (nfc_dev->nfc_vbat_monitor.vbat_monitor_status) {
|
||||
pr_debug("%s: NFC recovering state\n",
|
||||
__func__);
|
||||
nfc_dev->nfc_vbat_monitor.vbat_monitor_status =
|
||||
false;
|
||||
ret = -EREMOTEIO;
|
||||
goto err;
|
||||
}
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
i2c_disable_irq(nfc_dev);
|
||||
|
||||
if (gpio_get_value(nfc_gpio->irq))
|
||||
@@ -414,6 +427,13 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
pr_err("NxpDrv: %s: request_irq failed\n", __func__);
|
||||
goto err_nfc_misc_unregister;
|
||||
}
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
ret = nfc_vbat_monitor_init(nfc_dev, nfc_gpio, client);
|
||||
if (ret) {
|
||||
pr_err("%s: nfcc vbat monitor init failed, ret: %d\n", __func__, ret);
|
||||
//goto err_nfc_misc_unregister;
|
||||
}
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
i2c_disable_irq(nfc_dev);
|
||||
|
||||
ret = nfc_ldo_config(&client->dev, nfc_dev);
|
||||
@@ -501,6 +521,11 @@ int nfc_i2c_dev_remove(struct i2c_client *client)
|
||||
|
||||
device_init_wakeup(&client->dev, false);
|
||||
free_irq(client->irq, nfc_dev);
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
if (gpio_is_valid(nfc_dev->nfc_vbat_monitor.irq_num)) {
|
||||
free_irq(nfc_dev->nfc_vbat_monitor.irq_num, nfc_dev);
|
||||
}
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
nfc_misc_unregister(nfc_dev, DEV_COUNT);
|
||||
mutex_destroy(&nfc_dev->dev_ref_mutex);
|
||||
mutex_destroy(&nfc_dev->read_mutex);
|
||||
@@ -532,6 +557,13 @@ int nfc_i2c_dev_suspend(struct device *device)
|
||||
if (!enable_irq_wake(client->irq))
|
||||
i2c_dev->irq_wake_up = true;
|
||||
}
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
if (gpio_is_valid(nfc_dev->nfc_vbat_monitor.irq_num)) {
|
||||
if (enable_irq_wake(nfc_dev->nfc_vbat_monitor.irq_num) != 0) {
|
||||
pr_err("%s: vbat irq wake enabled failed\n", __func__);
|
||||
}
|
||||
}
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
pr_debug("NxpDrv: %s: irq_wake_up = %d", __func__, i2c_dev->irq_wake_up);
|
||||
return 0;
|
||||
}
|
||||
@@ -554,6 +586,13 @@ int nfc_i2c_dev_resume(struct device *device)
|
||||
if (!disable_irq_wake(client->irq))
|
||||
i2c_dev->irq_wake_up = false;
|
||||
}
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
if (gpio_is_valid(nfc_dev->nfc_vbat_monitor.irq_num)) {
|
||||
if (disable_irq_wake(nfc_dev->nfc_vbat_monitor.irq_num) != 0) {
|
||||
pr_err("%s: vbat irq wake disabled failed\n", __func__);
|
||||
}
|
||||
}
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
pr_debug("NxpDrv: %s: irq_wake_up = %d", __func__, i2c_dev->irq_wake_up);
|
||||
return 0;
|
||||
}
|
||||
|
||||
271
nxp/opensource/driver/nfc/nfc_vbat_monitor.c
Executable file
271
nxp/opensource/driver/nfc/nfc_vbat_monitor.c
Executable file
@@ -0,0 +1,271 @@
|
||||
/******************************************************************************
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <linux/compat.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* nfc_nci_data_read - This API can be used to read nci data packet.
|
||||
*
|
||||
* This function is called from nfc Init.
|
||||
*
|
||||
* @nfc_dev: the dev structure for driver.
|
||||
* @buf: to copy/get response message.
|
||||
* Return: -EREMOTEIO for transcieve error
|
||||
* No. of bytes read if Success(or no issue)
|
||||
*/
|
||||
int nfc_nci_data_read(struct nfc_dev *nfc_dev, char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
int length_byte = 0;
|
||||
unsigned char hdr_len = NCI_HDR_LEN;
|
||||
|
||||
ret = i2c_master_recv(nfc_dev->i2c_dev.client, buf, hdr_len);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: returned header error %d\n", __func__, ret);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
length_byte = buf[NCI_PAYLOAD_LEN_IDX];
|
||||
ret = i2c_master_recv(nfc_dev->i2c_dev.client, buf + hdr_len,
|
||||
length_byte);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: returned payload error %d\n", __func__, ret);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
return (hdr_len + length_byte);
|
||||
}
|
||||
|
||||
/**
|
||||
* perform_nfcc_initialization - used to send nci cmd through i2c
|
||||
*
|
||||
* Reset and init commands send to recover NFC
|
||||
*
|
||||
* @nfc_dev: nfc device data structure
|
||||
* Return: -EREMOTEIO for transcieve error
|
||||
* 0 if Success(or no issue)
|
||||
*/
|
||||
int perform_nfcc_initialization(struct nfc_dev *nfc_dev)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char cmd_reset_nci[] = { 0x20, 0x00, 0x01, 0x00 };
|
||||
unsigned char cmd_init_nci[] = { 0x20, 0x01, 0x02, 0x00, 0x00 };
|
||||
unsigned char cmd_read_buff[MAX_NCI_BUFFER_SIZE];
|
||||
|
||||
gpio_set_ven(nfc_dev, 0);
|
||||
gpio_set_ven(nfc_dev, 1);
|
||||
do {
|
||||
msleep(NFC_RST_CMD_READ_DELAY_MS);
|
||||
if (nfc_dev->nfc_write(nfc_dev, cmd_reset_nci, sizeof(cmd_reset_nci),
|
||||
NO_RETRY) <= 0)
|
||||
break;
|
||||
msleep(NFC_RST_CMD_READ_DELAY_MS);
|
||||
memset(cmd_read_buff, 0x00, sizeof(cmd_read_buff));
|
||||
if (nfc_nci_data_read(nfc_dev, cmd_read_buff) <= 0)
|
||||
break;
|
||||
msleep(NFC_RST_CMD_READ_DELAY_MS);
|
||||
memset(cmd_read_buff, 0x00, sizeof(cmd_read_buff));
|
||||
if (nfc_nci_data_read(nfc_dev, cmd_read_buff) <= 0)
|
||||
break;
|
||||
msleep(NFC_RST_CMD_READ_DELAY_MS);
|
||||
if (nfc_dev->nfc_write(nfc_dev, cmd_init_nci, sizeof(cmd_init_nci),
|
||||
NO_RETRY) <= 0)
|
||||
break;
|
||||
msleep(NFC_RST_CMD_READ_DELAY_MS);
|
||||
memset(cmd_read_buff, 0x00, sizeof(cmd_read_buff));
|
||||
if (nfc_nci_data_read(nfc_dev, cmd_read_buff) <= 0)
|
||||
break;
|
||||
if (cmd_read_buff[0] == 0x40 && cmd_read_buff[1] == 0x01 &&
|
||||
cmd_read_buff[3] == 0x00)
|
||||
return 0;
|
||||
} while (0);
|
||||
ret = -EREMOTEIO;
|
||||
pr_err("%s: no response for nci cmd, ret: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfcc_vbat_recovery - To recover the nfcc from unresponse state due to low vbat.
|
||||
*
|
||||
* send nfcc recovery for NFC_VBAT_MONITOR_MAX_RETRY_COUNT times
|
||||
*
|
||||
* @nfc_dev: nfc device data structure
|
||||
* Return: -EREMOTEIO for transcieve error
|
||||
* 0 if Success(or no issue)
|
||||
*/
|
||||
int nfcc_vbat_recovery(struct nfc_dev *nfc_dev)
|
||||
{
|
||||
int ret = -EREMOTEIO;
|
||||
unsigned char retrycount = 0;
|
||||
|
||||
do {
|
||||
msleep(NFC_RESET_RETRY_DELAY_MS);
|
||||
ret = perform_nfcc_initialization(nfc_dev);
|
||||
if (ret == 0) {
|
||||
pr_err("%s: nfcc recovery is success and vbat irq enabled\n",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
pr_err("%s: recovering from vbat trigger, count: %d ret: %d\n",
|
||||
__func__, retrycount, ret);
|
||||
retrycount++;
|
||||
} while (retrycount < NFC_VBAT_MONITOR_MAX_RETRY_COUNT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfc_vbat_monitor_irq_handler - Handler function for vbat interrupt
|
||||
*
|
||||
* Initialises workqueue after disabling interrupt if present
|
||||
*
|
||||
* @irq: interrupt
|
||||
* @dev_id: nfc device pointer
|
||||
* Return: Status of type irqreturn_t
|
||||
*/
|
||||
irqreturn_t nfc_vbat_monitor_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct nfc_dev *nfc_dev = dev_id;
|
||||
|
||||
spin_lock_irqsave(
|
||||
&nfc_dev->nfc_vbat_monitor.nfc_vbat_monitor_enabled_lock,
|
||||
flags);
|
||||
disable_irq_nosync(nfc_dev->nfc_vbat_monitor.irq_num);
|
||||
if (!queue_work(nfc_dev->nfc_vbat_monitor.wq,
|
||||
&nfc_dev->nfc_vbat_monitor.work))
|
||||
pr_err("%s: queue_work success\n", __func__);
|
||||
spin_unlock_irqrestore(
|
||||
&nfc_dev->nfc_vbat_monitor.nfc_vbat_monitor_enabled_lock,
|
||||
flags);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfc_vbat_monitor_workqueue_handler - Handler for workqueue of vbat interrupt
|
||||
*
|
||||
* Enables interrupt workqueue and initialises recovery of nfcc
|
||||
*
|
||||
* @work: workqueue structure
|
||||
*/
|
||||
static void nfc_vbat_monitor_workqueue_handler(struct work_struct *work)
|
||||
{
|
||||
int ret = 0;
|
||||
struct nfc_vbat_monitor *nfc_vbat_monitor =
|
||||
container_of(work, struct nfc_vbat_monitor, work);
|
||||
struct nfc_dev *nfc_dev = container_of(nfc_vbat_monitor, struct nfc_dev,
|
||||
nfc_vbat_monitor);
|
||||
|
||||
pr_err("%s: read pending status flag: %d\n", __func__,
|
||||
nfc_dev->cold_reset.is_nfc_read_pending);
|
||||
nfc_dev->nfc_disable_intr(nfc_dev);
|
||||
mutex_lock(&nfc_dev->write_mutex);
|
||||
ret = nfcc_vbat_recovery(nfc_dev);
|
||||
if (ret == 0)
|
||||
enable_irq(nfc_dev->nfc_vbat_monitor.irq_num);
|
||||
if (nfc_dev->cold_reset.is_nfc_read_pending == false) {
|
||||
if (ret != 0) {
|
||||
pr_err("%s nfcc recovery failed, enabling irq",
|
||||
__func__);
|
||||
enable_irq(nfc_dev->nfc_vbat_monitor.irq_num);
|
||||
}
|
||||
} else {
|
||||
nfc_dev->nfc_vbat_monitor.vbat_monitor_status = true;
|
||||
wake_up(&nfc_dev->read_wq);
|
||||
}
|
||||
mutex_unlock(&nfc_dev->write_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfc_vbat_monitor_init_workqueue - Workqueue initialiser for vbat interrupt
|
||||
*
|
||||
* Allocates workqueue and intiialises it
|
||||
*
|
||||
* @nfc_vbat_monitor: nfc_vbat_monitor structure of platform for nfc
|
||||
* Return: 0 if Success
|
||||
*/
|
||||
int nfc_vbat_monitor_init_workqueue(struct nfc_vbat_monitor *nfc_vbat_monitor)
|
||||
{
|
||||
nfc_vbat_monitor->wq =
|
||||
alloc_workqueue(NFC_VBAT_MONITOR_WORKQUEUE_NAME, 0, 0);
|
||||
|
||||
if (!nfc_vbat_monitor->wq)
|
||||
pr_err("%s: failed to allocate workqueue\n", __func__);
|
||||
INIT_WORK(&nfc_vbat_monitor->work, nfc_vbat_monitor_workqueue_handler);
|
||||
pr_debug("%s: allocated workqueue\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfc_vbat_monitor_init - interrupt initialization for vbat handling
|
||||
*
|
||||
* Configures vbat gpio and assigns an interrupt number, calls for
|
||||
* workqueue intialization
|
||||
*
|
||||
* @nfc_dev: nfc device data structure
|
||||
* @nfc_gpio: platform gpio structure
|
||||
* @client: i2c client
|
||||
* Return: -1 if initialization failed
|
||||
* 0 if Success(or no issue)
|
||||
*/
|
||||
int nfc_vbat_monitor_init(struct nfc_dev *nfc_dev,
|
||||
struct platform_gpio *nfc_gpio,
|
||||
struct i2c_client *client)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
do {
|
||||
ret = configure_gpio(nfc_gpio->vbat_irq, GPIO_IRQ);
|
||||
if (ret <= 0) {
|
||||
pr_err("%s: unable to request nfc vbat gpio [%d]\n", __func__,
|
||||
nfc_gpio->vbat_irq);
|
||||
break;
|
||||
}
|
||||
nfc_dev->nfc_vbat_monitor.irq_num = ret;
|
||||
/* init mutex and queues */
|
||||
spin_lock_init(
|
||||
&nfc_dev->nfc_vbat_monitor.nfc_vbat_monitor_enabled_lock);
|
||||
nfc_dev->nfc_vbat_monitor.vbat_monitor_status = false;
|
||||
ret = request_irq(nfc_dev->nfc_vbat_monitor.irq_num,
|
||||
nfc_vbat_monitor_irq_handler,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
nfc_dev->i2c_dev.client->name, nfc_dev);
|
||||
if (ret) {
|
||||
pr_err("%s: irq request failed\n", __func__);
|
||||
break;
|
||||
}
|
||||
ret = nfc_vbat_monitor_init_workqueue(&nfc_dev->nfc_vbat_monitor);
|
||||
if (ret) {
|
||||
pr_err("%s: nfc_gpio workqueue init failed\n", __func__);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
} while (0);
|
||||
pr_err("%s: vbat monitor initialization failed, ret:%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
47
nxp/opensource/driver/nfc/nfc_vbat_monitor.h
Executable file
47
nxp/opensource/driver/nfc/nfc_vbat_monitor.h
Executable file
@@ -0,0 +1,47 @@
|
||||
/******************************************************************************
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//#if IS_ENABLED(CONFIG_NXP_NFC_VBAT_MONITOR)
|
||||
#ifndef _NFC_VBAT_MONITOR_H_
|
||||
#define _NFC_VBAT_MONITOR_H_
|
||||
|
||||
#include <linux/cdev.h>
|
||||
|
||||
#define NXP_NFC_VBAT_MONITOR
|
||||
#define NFC_VBAT_MONITOR_MAX_RETRY_COUNT (3)
|
||||
#define NFC_RESET_RETRY_DELAY_MS (500)
|
||||
#define NFC_RST_CMD_READ_DELAY_MS (50)
|
||||
#define NFC_VBAT_MONITOR_WORKQUEUE_NAME "nfc_vbat_monitor_workq"
|
||||
#define DTS_NFC_VBAT_MONITOR_STR "nxp,sn-vbat"
|
||||
|
||||
/* vbat monitoring specific parameters*/
|
||||
struct nfc_vbat_monitor {
|
||||
spinlock_t nfc_vbat_monitor_enabled_lock;
|
||||
struct workqueue_struct *wq;
|
||||
struct work_struct work;
|
||||
int irq_num;
|
||||
bool vbat_monitor_status;
|
||||
};
|
||||
|
||||
/* vbat monitoring handling and workqueue functions*/
|
||||
irqreturn_t nfc_vbat_monitor_irq_handler(int irq, void *dev_id);
|
||||
int nfc_vbat_monitor_init_workqueue(struct nfc_vbat_monitor *nfc_vbat_monitor);
|
||||
|
||||
#endif /* _NFC_VBAT_MONITOR_H_ */
|
||||
//#endif /* CONFIG_NXP_NFC_VBAT_MONITOR */
|
||||
Reference in New Issue
Block a user