123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881 |
- /******************************************************************************
- *
- * Copyright 2012-2023 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
- *
- ******************************************************************************/
- /**
- * \addtogroup spi_driver
- *
- * @{ */
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/list.h>
- #include <linux/irq.h>
- #include <linux/jiffies.h>
- #include <linux/uaccess.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
- #include <linux/io.h>
- #include <linux/platform_device.h>
- #include <linux/gpio.h>
- #include <linux/of_gpio.h>
- #include <linux/miscdevice.h>
- #include <linux/spinlock.h>
- #include <linux/spi/spi.h>
- #include <linux/sched.h>
- #include <linux/poll.h>
- #include <linux/ktime.h>
- #include <linux/regulator/consumer.h>
- #include <linux/pinctrl/consumer.h>
- #include <linux/spi/spidev.h>
- #include <linux/of_platform.h>
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- #include <linux/rcupdate.h>
- #if IS_ENABLED(CONFIG_SPI_MSM_GENI)
- #include "nfc_wakelock.h"
- #if IS_ENABLED(CONFIG_MSM_GENI_SE)
- #include <linux/msm-geni-se.h>
- #include <linux/msm_gpi.h>
- #endif
- #endif
- #endif
- #include "p73.h"
- #include "common_ese.h"
- #include "ese_reset.h"
- #define DRAGON_P61 0
- /* Device driver's configuration macro */
- /* Macro to configure poll/interrupt based req*/
- #undef P61_IRQ_ENABLE
- //#define P61_IRQ_ENABLE
- /* Macro to configure Hard/Soft reset to P61 */
- //#define P61_HARD_RESET
- #undef P61_HARD_RESET
- #ifdef P61_HARD_RESET
- static struct regulator *p61_regulator = NULL;
- #else
- #endif
- #define P61_IRQ 33 /* this is the same used in omap3beagle.c */
- #define P61_RST 138
- /* Macro to define SPI clock frequency */
- //#define P61_SPI_CLOCK_7Mzh
- #undef P61_SPI_CLOCK_7Mzh
- #undef P61_SPI_CLOCK_13_3_Mzh
- #undef P61_SPI_CLOCK_8Mzh
- #undef P61_SPI_CLOCK_20Mzh
- #define P61_SPI_CLOCK_25Mzh
- #ifdef P61_SPI_CLOCK_13_3_Mzh
- //#define P61_SPI_CLOCK 13300000L;Further debug needed
- #define P61_SPI_CLOCK 19000000L;
- #else
- #ifdef P61_SPI_CLOCK_7Mzh
- #define P61_SPI_CLOCK 7000000L;
- #else
- #ifdef P61_SPI_CLOCK_8Mzh
- #define P61_SPI_CLOCK 8000000L;
- #else
- #ifdef P61_SPI_CLOCK_20Mzh
- #define P61_SPI_CLOCK 20000000L;
- #else
- #ifdef P61_SPI_CLOCK_25Mzh
- #define P61_SPI_CLOCK 25000000L;
- #else
- #define P61_SPI_CLOCK 4000000L;
- #endif
- #endif
- #endif
- #endif
- #endif
- /* size of maximum read/write buffer supported by driver */
- #ifdef MAX_BUFFER_SIZE
- #undef MAX_BUFFER_SIZE
- #endif //MAX_BUFFER_SIZE
- #define MAX_BUFFER_SIZE 780U
- /* Different driver debug lever */
- enum P61_DEBUG_LEVEL {
- P61_DEBUG_OFF,
- P61_FULL_DEBUG
- };
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- static char *p61_pinctrl_name[] = {"ese_off", "ese_on", "lpm", "default", "active", "suspend"};
- enum p61_pin_ctrl {
- P61_PIN_CTRL_ESE_OFF,
- P61_PIN_CTRL_ESE_ON,
- P61_PIN_CTRL_LPM,
- P61_PIN_CTRL_DEFAULT,
- P61_PIN_CTRL_ACTIVE,
- P61_PIN_CTRL_SUSPEND,
- P61_PIN_CTRL_MAX
- };
- #endif
- /* Variable to store current debug level request by ioctl */
- static unsigned char debug_level;
- static DEFINE_MUTEX(open_close_mutex);
- #define P61_DBG_MSG(msg...) \
- switch(debug_level) \
- { \
- case P61_DEBUG_OFF: \
- break; \
- case P61_FULL_DEBUG: \
- printk(KERN_INFO "[NXP-P61] : " msg); \
- break; \
- default: \
- printk(KERN_ERR "[NXP-P61] : Wrong debug level %d", debug_level); \
- break; \
- } \
- #define P61_ERR_MSG(msg...) printk(KERN_ERR "[NFC-P61] : " msg );
- /* Device specific macro and structure */
- struct p61_dev {
- wait_queue_head_t read_wq; /* wait queue for read interrupt */
- struct mutex read_mutex; /* read mutex */
- struct mutex write_mutex; /* write mutex */
- struct spi_device *spi; /* spi device structure */
- struct miscdevice p61_device; /* char device as misc driver */
- int rst_gpio; /* SW Reset gpio */
- int irq_gpio; /* P61 will interrupt DH for any ntf */
- bool irq_enabled; /* flag to indicate irq is used */
- unsigned char enable_poll_mode; /* enable the poll mode */
- spinlock_t irq_enabled_lock; /*spin lock for read irq */
- int trusted_ese_gpio; /* i/p to eSE to distunguish trusted Session */
- ese_spi_transition_state_t ese_spi_transition_state; /* State of the driver */
- struct device *nfcc_device; /*nfcc driver handle for driver to driver comm */
- struct nfc_dev *nfcc_data;
- const char *nfcc_name;
- bool gpio_coldreset;
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- int ap_vendor;
- struct device_node *nfc_node;
- struct pinctrl *pinctrl;
- struct pinctrl_state *pinctrl_state[P61_PIN_CTRL_MAX];
- struct platform_device *spi_pdev;
- struct nfc_wake_lock ese_lock;
- int open_pid;
- int release_pid;
- char open_task_name[TASK_COMM_LEN];
- char release_task_name[TASK_COMM_LEN];
- #if IS_ENABLED(CONFIG_SPI_MSM_GENI)
- struct delayed_work spi_release_work;
- struct nfc_wake_lock spi_release_wakelock;
- #endif
- #endif
- unsigned char *r_buf;
- unsigned char *w_buf;
- };
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- struct device *g_nfc_device;
- struct p61_dev *g_p61_dev;
- #endif
- /* T==1 protocol specific global data */
- const unsigned char SOF = 0xA5u;
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- static void p61_get_task_info(struct p61_dev *p61_dev, char *task_name, int *pid)
- {
- struct task_struct *task;
- if (!p61_dev)
- return;
- rcu_read_lock();
- *pid = task_pid_nr(current);
- task = pid_task(find_vpid(*pid), PIDTYPE_PID);
- if (task) {
- memcpy(task_name, task->comm, TASK_COMM_LEN);
- task_name[TASK_COMM_LEN - 1] = '\0';
- }
- rcu_read_unlock();
- }
- static void p61_init_task_info(struct p61_dev *p61_dev)
- {
- p61_dev->open_pid = 0;
- p61_dev->release_pid = 0;
- memset(p61_dev->open_task_name, 0, TASK_COMM_LEN);
- memset(p61_dev->release_task_name, 0, TASK_COMM_LEN);
- }
- void p61_print_status(const char *func_name)
- {
- struct p61_dev *p61_dev = g_p61_dev;
- if (!p61_dev)
- return;
- NFC_LOG_INFO("%s: state=%d o_pid=%d rel_pid=%d o_task=%s rel_task=%s\n",
- func_name, p61_dev->ese_spi_transition_state,
- p61_dev->open_pid,
- p61_dev->release_pid,
- p61_dev->open_task_name,
- p61_dev->release_task_name);
- }
- static void p61_pinctrl_select(struct p61_dev *p61_dev, enum p61_pin_ctrl stat)
- {
- int ret;
- NFC_LOG_INFO("pinctrl[%s]\n", p61_pinctrl_name[stat]);
- if (!p61_dev->pinctrl || !p61_dev->pinctrl_state[stat])
- return;
- ret = pinctrl_select_state(p61_dev->pinctrl, p61_dev->pinctrl_state[stat]);
- if (ret < 0)
- NFC_LOG_INFO("pinctrl[%d] failed\n", stat);
- }
- #if IS_ENABLED(CONFIG_SPI_MSM_GENI)
- static void p61_spi_release_work(struct work_struct *work)
- {
- struct p61_dev *p61_dev = g_p61_dev;
- if (p61_dev == NULL) {
- NFC_LOG_ERR("%s: spi probe is not called\n", __func__);
- return;
- }
- NFC_LOG_INFO("release ese spi\n");
- p61_pinctrl_select(p61_dev, P61_PIN_CTRL_SUSPEND); /* for QC AP */
- }
- #endif
- #endif
- /**
- * \ingroup spi_driver
- * \brief Will be called on device close to release resources
- *
- * \param[in] struct inode *
- * \param[in] struct file *
- *
- * \retval 0 if ok.
- *
- */
- static int p61_dev_release(struct inode *inode, struct file *filp)
- {
- struct p61_dev *p61_dev = NULL;
- NFC_LOG_INFO("Enter %s: ESE driver release\n", __func__);
- mutex_lock(&open_close_mutex);
- p61_dev = filp->private_data;
- p61_dev->ese_spi_transition_state = ESE_SPI_IDLE;
- #if !IS_ENABLED(CONFIG_SAMSUNG_NFC)
- gpio_set_value(p61_dev->trusted_ese_gpio, 0);
- #endif
- nfc_ese_pwr(p61_dev->nfcc_data, ESE_RST_PROT_DIS);
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- p61_pinctrl_select(p61_dev, P61_PIN_CTRL_ESE_OFF); /* for LSI AP */
- #if IS_ENABLED(CONFIG_SPI_MSM_GENI)
- schedule_delayed_work(&p61_dev->spi_release_work,
- msecs_to_jiffies(2000));
- wake_lock_timeout(&p61_dev->spi_release_wakelock,
- msecs_to_jiffies(2100));
- #endif
- if (wake_lock_active(&p61_dev->ese_lock))
- wake_unlock(&p61_dev->ese_lock);
- #endif
- mutex_unlock(&open_close_mutex);
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- p61_get_task_info(p61_dev, p61_dev->release_task_name, &p61_dev->release_pid);
- p61_print_status(__func__);
- #endif
- NFC_LOG_INFO("Exit %s: ESE driver release\n", __func__);
- return 0;
- }
- static int p61_xfer(struct p61_dev *p61_dev,
- struct p61_ioctl_transfer *tr)
- {
- int status = 0;
- struct spi_message m;
- struct spi_transfer t;
- static u32 read_try_cnt;
- /*For SDM845 & linux4.9: need to change spi buffer
- * from stack to dynamic memory
- */
- if (p61_dev == NULL || tr == NULL)
- return -EFAULT;
- if (tr->len > MAX_BUFFER_SIZE || !tr->len)
- return -EMSGSIZE;
- spi_message_init(&m);
- memset(&t, 0, sizeof(t));
- memset(p61_dev->w_buf, 0, tr->len); /*memset 0 for write */
- memset(p61_dev->r_buf, 0, tr->len); /*memset 0 for read */
- if (tr->tx_buffer != NULL) { /*write */
- if (copy_from_user(p61_dev->w_buf, tr->tx_buffer, tr->len) != 0) {
- NFC_LOG_ERR("p61_wr: copy_from_user fail %d\n", tr->len);
- status = -EFAULT;
- goto xfer_exit;
- }
- }
- t.rx_buf = p61_dev->r_buf;
- t.tx_buf = p61_dev->w_buf;
- t.len = tr->len;
- spi_message_add_tail(&t, &m);
- status = spi_sync(p61_dev->spi, &m);
- if (status == 0) {
- if (tr->rx_buffer != NULL) { /*read */
- unsigned long missing = 0;
- missing = copy_to_user(tr->rx_buffer, p61_dev->r_buf, tr->len);
- if (missing != 0)
- tr->len = tr->len - (unsigned int)missing;
- }
- }
- if (tr->tx_buffer != NULL) {
- if (read_try_cnt)
- NFC_LOG_REC("p61w%d try%u\n", tr->len, read_try_cnt);
- else
- NFC_LOG_REC("p61w%d\n", tr->len);
- }
- if (tr->rx_buffer != NULL) {
- if (tr->len == 2 && ((p61_dev->r_buf[0] == 0x0 && p61_dev->r_buf[2] == 0x0) ||
- (p61_dev->r_buf[0] == 0xff && p61_dev->r_buf[2] == 0xff))) {
- read_try_cnt++;
- } else {
- if (read_try_cnt)
- NFC_LOG_REC("p61r%d try%u\n", tr->len, read_try_cnt);
- else
- NFC_LOG_REC("p61r%d\n", tr->len);
- read_try_cnt = 0;
- }
- }
- xfer_exit:
- return status;
- } /* vfsspi_xfer */
- static int p61_rw_spi_message(struct p61_dev *p61_dev,
- unsigned long arg)
- {
- struct p61_ioctl_transfer *dup = NULL;
- int err = 0;
- dup = kmalloc(sizeof(struct p61_ioctl_transfer), GFP_KERNEL);
- if (dup == NULL)
- return -ENOMEM;
- if (copy_from_user(dup, (void *)arg,
- sizeof(struct p61_ioctl_transfer)) != 0) {
- kfree(dup);
- return -EFAULT;
- }
- err = p61_xfer(p61_dev, dup);
- if (err != 0) {
- kfree(dup);
- NFC_LOG_ERR("%s: p61_xfer failed, %d\n", __func__, err);
- return err;
- }
- if (copy_to_user((void *)arg, dup,
- sizeof(struct p61_ioctl_transfer)) != 0) {
- kfree(dup);
- return -EFAULT;
- }
- kfree(dup);
- return 0;
- }
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- void store_nfc_i2c_device(struct device *nfc_i2c_dev)
- {
- g_nfc_device = nfc_i2c_dev;
- }
- #endif
- #ifdef CONFIG_COMPAT
- static int p61_rw_spi_message_compat(struct p61_dev *p61_dev,
- unsigned long arg)
- {
- struct p61_ioctl_transfer32 __user *argp = compat_ptr(arg);
- struct p61_ioctl_transfer32 it32;
- struct p61_ioctl_transfer *dup = NULL;
- int err = 0;
- dup = kmalloc(sizeof(struct p61_ioctl_transfer), GFP_KERNEL);
- if (dup == NULL)
- return -ENOMEM;
- if (copy_from_user(&it32, argp, sizeof(it32))) {
- kfree(dup);
- return -EFAULT;
- }
- dup->rx_buffer = (__u8 *)(uintptr_t)it32.rx_buffer;
- dup->tx_buffer = (__u8 *)(uintptr_t)it32.tx_buffer;
- dup->len = it32.len;
- err = p61_xfer(p61_dev, dup);
- if (err != 0) {
- kfree(dup);
- NFC_LOG_ERR("%s: p61_xfer failed, %d\n", __func__, err);
- return err;
- }
- if (it32.rx_buffer) {
- if (__put_user(dup->len, &argp->len)) {
- kfree(dup);
- return -EFAULT;
- }
- }
- kfree(dup);
- return 0;
- }
- #endif /*CONFIG_COMPAT */
- /**
- * \ingroup spi_driver
- * \brief Called from SPI LibEse to initilaize the P61 device
- *
- * \param[in] struct inode *
- * \param[in] struct file *
- *
- * \retval 0 if ok.
- *
- */
- static int p61_dev_open(struct inode *inode, struct file *filp)
- {
- #ifdef CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE
- struct p61_dev *p61_dev = g_p61_dev;
- if (p61_dev == NULL) {
- NFC_LOG_ERR("%s: spi probe is not called\n", __func__);
- return -EAGAIN;
- }
- #else
- struct p61_dev
- *p61_dev = container_of(filp->private_data,
- struct p61_dev,
- p61_device);
- #endif
- /* Find the NFC parent device if it exists. */
- if (p61_dev != NULL && p61_dev->nfcc_data == NULL) {
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- struct device *nfc_dev = g_nfc_device;
- if (!nfc_dev) {
- NFC_LOG_ERR("%s: cannot find NFC controller\n", __func__);
- return -ENODEV;
- }
- #else
- struct device *nfc_dev = bus_find_device_by_name(&i2c_bus_type, NULL,
- p61_dev->nfcc_name);
- if (!nfc_dev) {
- NFC_LOG_ERR("%s: cannot find NFC controller '%s'\n", __func__,
- p61_dev->nfcc_name);
- return -ENODEV;
- }
- #endif
- p61_dev->nfcc_data = dev_get_drvdata(nfc_dev);
- if (!p61_dev->nfcc_data) {
- NFC_LOG_ERR("%s: cannot find NFC controller device data\n", __func__);
- put_device(nfc_dev);
- return -ENODEV;
- }
- P61_DBG_MSG("%s: NFC controller found\n", __func__);
- p61_dev->nfcc_device = nfc_dev;
- }
- filp->private_data = p61_dev;
- if(p61_dev->ese_spi_transition_state == ESE_SPI_BUSY) {
- NFC_LOG_ERR("%s : ESE is busy\n", __func__);
- return -EBUSY;
- }
- mutex_lock(&open_close_mutex);
- p61_dev->ese_spi_transition_state = ESE_SPI_BUSY;
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- /* for checking previous open/close tasks */
- p61_print_status("p61_dev_open pre");
- #if IS_ENABLED(CONFIG_SPI_MSM_GENI)
- cancel_delayed_work_sync(&p61_dev->spi_release_work);
- #endif
- if (!wake_lock_active(&p61_dev->ese_lock))
- wake_lock(&p61_dev->ese_lock);
- p61_pinctrl_select(p61_dev, P61_PIN_CTRL_ESE_ON);
- if (p61_dev->ap_vendor != AP_VENDOR_QCT)
- msleep(60);
- #endif
- mutex_unlock(&open_close_mutex);
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- p61_init_task_info(p61_dev);
- p61_get_task_info(p61_dev, p61_dev->open_task_name, &p61_dev->open_pid);
- p61_print_status(__func__);
- #endif
- return 0;
- }
- /**
- * \ingroup spi_driver
- * \brief To configure the P61_SET_PWR/P61_SET_DBG/P61_SET_POLL
- * \n P61_SET_PWR - hard reset (arg=2), soft reset (arg=1)
- * \n P61_SET_DBG - Enable/Disable (based on arg value) the driver logs
- * \n P61_SET_POLL - Configure the driver in poll (arg = 1), interrupt (arg = 0) based read operation
- * \param[in] struct file *
- * \param[in] unsigned int
- * \param[in] unsigned long
- *
- * \retval 0 if ok.
- *
- */
- static long p61_dev_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg)
- {
- int ret = 0;
- struct p61_dev *p61_dev = NULL;
- #if !IS_ENABLED(CONFIG_SAMSUNG_NFC)
- unsigned char buf[100];
- #endif
- P61_DBG_MSG(KERN_ALERT "p61_dev_ioctl-Enter %u arg = %ld\n", cmd, arg);
- p61_dev = filp->private_data;
- switch (cmd) {
- case P61_SET_PWR:
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- if (arg == 2)
- NFC_LOG_INFO("[NXP-P61] - P61_SET_PWR. No Action.\n");
- #else
- if (arg == 2) {
- #ifdef P61_HARD_RESET
- P61_DBG_MSG(KERN_ALERT " Disabling p61_regulator");
- if (p61_regulator != NULL) {
- regulator_disable(p61_regulator);
- msleep(50);
- regulator_enable(p61_regulator);
- P61_DBG_MSG(KERN_ALERT " Enabling p61_regulator");
- } else {
- NFC_LOG_ERR(KERN_ALERT " ERROR : p61_regulator is not enabled\n");
- }
- #endif
- } else if (arg == 1) {
- P61_DBG_MSG(KERN_ALERT " Soft Reset");
- //gpio_set_value(p61_dev->rst_gpio, 1);
- //msleep(20);
- gpio_set_value(p61_dev->rst_gpio, 0);
- msleep(50);
- ret = spi_read(p61_dev->spi, (void *)buf, sizeof(buf));
- msleep(50);
- gpio_set_value(p61_dev->rst_gpio, 1);
- msleep(20);
- }
- #endif
- break;
- case P61_SET_DBG:
- debug_level = (unsigned char)arg;
- NFC_LOG_INFO("[NXP-P61] - Debug level %d\n",
- debug_level);
- break;
- case P61_SET_POLL:
- p61_dev->enable_poll_mode = (unsigned char)arg;
- if (p61_dev->enable_poll_mode == 0) {
- NFC_LOG_INFO("[NXP-P61] - IRQ Mode is set\n");
- } else {
- NFC_LOG_INFO("[NXP-P61] - Poll Mode is set\n");
- p61_dev->enable_poll_mode = 1;
- }
- break;
- case P61_RW_SPI_DATA:
- ret = p61_rw_spi_message(p61_dev, arg);
- break;
- case P61_SET_SPM_PWR:
- NFC_LOG_INFO("P61_SET_SPM_PWR: enter\n");
- ret = nfc_ese_pwr(p61_dev->nfcc_data, arg);
- NFC_LOG_INFO("P61_SET_SPM_PWR: exit\n");
- break;
- case P61_GET_SPM_STATUS:
- NFC_LOG_INFO("P61_GET_SPM_STATUS: enter\n");
- ret = nfc_ese_pwr(p61_dev->nfcc_data, ESE_POWER_STATE);
- NFC_LOG_INFO("P61_GET_SPM_STATUS: exiti\n");
- break;
- case P61_SET_DWNLD_STATUS:
- NFC_LOG_INFO("P61_SET_DWNLD_STATUS: enter\n");
- //ret = nfc_dev_ioctl(filp, PN544_SET_DWNLD_STATUS, arg);
- NFC_LOG_INFO("P61_SET_DWNLD_STATUS: =%lu exit\n", arg);
- break;
- case P61_GET_ESE_ACCESS:
- NFC_LOG_INFO("P61_GET_ESE_ACCESS: enter\n");
- //ret = nfc_dev_ioctl(filp, P544_GET_ESE_ACCESS, arg);
- NFC_LOG_INFO("P61_GET_ESE_ACCESS ret: %d exit\n", ret);
- break;
- case P61_SET_POWER_SCHEME:
- NFC_LOG_INFO("P61_SET_POWER_SCHEME: enter\n");
- //ret = nfc_dev_ioctl(filp, P544_SET_POWER_SCHEME, arg);
- NFC_LOG_INFO("P61_SET_POWER_SCHEME ret: %d exit\n",
- ret);
- break;
- case P61_INHIBIT_PWR_CNTRL:
- NFC_LOG_INFO("P61_INHIBIT_PWR_CNTRL: enter\n");
- //ret = nfc_dev_ioctl(filp, P544_SECURE_TIMER_SESSION, arg);
- NFC_LOG_INFO("P61_INHIBIT_PWR_CNTRL ret: %d exit\n",
- ret);
- break;
- case ESE_PERFORM_COLD_RESET:
- NFC_LOG_INFO("ESE_PERFORM_COLD_RESET: enter\n");
- if (p61_dev->gpio_coldreset)
- ret = perform_ese_gpio_reset(p61_dev->rst_gpio);
- else
- ret = nfc_ese_pwr(p61_dev->nfcc_data, ESE_CLD_RST);
- NFC_LOG_INFO("ESE_PERFORM_COLD_RESET ret: %d exit\n", ret);
- break;
- case PERFORM_RESET_PROTECTION:
- if (p61_dev->gpio_coldreset) {
- NFC_LOG_INFO("PERFORM_RESET_PROTECTION is not required and not supported\n");
- } else {
- NFC_LOG_INFO("PERFORM_RESET_PROTECTION: enter\n");
- ret = nfc_ese_pwr(p61_dev->nfcc_data,
- (arg == 1 ? ESE_RST_PROT_EN : ESE_RST_PROT_DIS));
- NFC_LOG_INFO("PERFORM_RESET_PROTECTION ret: %d exit\n", ret);
- }
- break;
- case ESE_SET_TRUSTED_ACCESS:
- NFC_LOG_INFO("Enter %s: TRUSTED access enabled=%lu\n", __func__, arg);
- #if !IS_ENABLED(CONFIG_SAMSUNG_NFC)
- if(arg == 1) {
- NFC_LOG_INFO("ESE_SET_TRUSTED_ACCESS: enter Enabling\n");
- gpio_set_value(p61_dev->trusted_ese_gpio, 1);
- NFC_LOG_INFO("ESE_SET_TRUSTED_ACCESS ret: exit\n");
- } else if (arg == 0) {
- NFC_LOG_INFO("ESE_SET_TRUSTED_ACCESS: enter Disabling\n");
- gpio_set_value(p61_dev->trusted_ese_gpio, 0);
- NFC_LOG_INFO("ESE_SET_TRUSTED_ACCESS ret: exit\n");
- }
- #endif
- break;
- default:
- NFC_LOG_ERR("Error case\n");
- ret = -EINVAL;
- }
- P61_DBG_MSG(KERN_ALERT "p61_dev_ioctl-exit %u arg = %lu\n", cmd, arg);
- return ret;
- }
- #ifdef CONFIG_COMPAT
- /**
- * \ingroup spi_driver
- * \brief To configure the P61_SET_PWR/P61_SET_DBG/P61_SET_POLL
- * \n P61_SET_PWR - hard reset (arg=2), soft reset (arg=1)
- * \n P61_SET_DBG - Enable/Disable (based on arg value) the driver logs
- * \n P61_SET_POLL - Configure the driver in poll (arg = 1), interrupt (arg = 0) based read operation
- * \param[in] struct file *
- * \param[in] unsigned int
- * \param[in] unsigned long
- *
- * \retval 0 if ok.
- *
- */
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- static long p61_dev_compat_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg)
- {
- int ret = 0;
- struct p61_dev *p61_dev = NULL;
- if (_IOC_TYPE(cmd) != P61_MAGIC)
- return -ENOTTY;
- p61_dev = filp->private_data;
- switch (cmd) {
- case P61_SET_PWR_COMPAT:
- if (arg == 2)
- NFC_LOG_INFO("%s: P61_SET_PWR. No Action.\n", __func__);
- break;
- case P61_SET_DBG_COMPAT:
- debug_level = (unsigned char)arg;
- P61_DBG_MSG(KERN_INFO"[NXP-P61] - Debug level %d",
- debug_level);
- break;
- case P61_SET_POLL_COMPAT:
- p61_dev->enable_poll_mode = (unsigned char)arg;
- if (p61_dev->enable_poll_mode == 0) {
- P61_DBG_MSG(KERN_INFO"[NXP-P61] - IRQ Mode is set\n");
- } else {
- P61_DBG_MSG(KERN_INFO"[NXP-P61] - Poll Mode is set\n");
- p61_dev->enable_poll_mode = 1;
- }
- break;
- case P61_RW_SPI_DATA_COMPAT:
- ret = p61_rw_spi_message_compat(p61_dev, arg);
- break;
- case P61_SET_SPM_PWR_COMPAT:
- NFC_LOG_INFO("%s: P61_SET_SPM_PWR: enter\n", __func__);
- ret = nfc_ese_pwr(p61_dev->nfcc_data, arg);
- NFC_LOG_INFO("%s: P61_SET_SPM_PWR: exit\n", __func__);
- break;
- case P61_GET_SPM_STATUS_COMPAT:
- NFC_LOG_INFO("%s: P61_GET_SPM_STATUS: enter\n", __func__);
- ret = nfc_ese_pwr(p61_dev->nfcc_data, ESE_POWER_STATE);
- NFC_LOG_INFO("%s: P61_GET_SPM_STATUS: exit\n", __func__);
- break;
- case P61_SET_DWNLD_STATUS_COMPAT:
- NFC_LOG_INFO("P61_SET_DWNLD_STATUS: enter\n");
- //ret = pn547_dev_ioctl(filp, PN547_SET_DWNLD_STATUS, arg);
- NFC_LOG_INFO("%s: P61_SET_DWNLD_STATUS: =%lu exit\n", __func__, arg);
- break;
- case P61_GET_ESE_ACCESS_COMPAT:
- NFC_LOG_INFO("P61_GET_ESE_ACCESS: enter\n");
- //ret = pn547_dev_ioctl(filp, P547_GET_ESE_ACCESS, arg);
- NFC_LOG_INFO("P61_GET_ESE_ACCESS ret: %d exit\n", ret);
- break;
- case P61_SET_POWER_SCHEME_COMPAT:
- NFC_LOG_INFO("P61_SET_POWER_SCHEME: enter\n");
- //ret = pn547_dev_ioctl(filp, P544_SET_POWER_SCHEME, arg);
- NFC_LOG_INFO("P61_SET_POWER_SCHEME ret: %d exit\n",
- ret);
- break;
- case P61_INHIBIT_PWR_CNTRL_COMPAT:
- NFC_LOG_INFO("P61_INHIBIT_PWR_CNTRL: enter\n");
- //ret = pn547_dev_ioctl(filp, P544_SECURE_TIMER_SESSION, arg);
- NFC_LOG_INFO("P61_INHIBIT_PWR_CNTRL ret: %d exit\n",
- ret);
- break;
- case ESE_PERFORM_COLD_RESET_COMPAT:
- NFC_LOG_INFO("ESE_PERFORM_COLD_RESET: enter\n");
- if (p61_dev->gpio_coldreset)
- ret = perform_ese_gpio_reset(p61_dev->rst_gpio);
- else
- ret = nfc_ese_pwr(p61_dev->nfcc_data, ESE_CLD_RST);
- NFC_LOG_INFO("ESE_PERFORM_COLD_RESET ret: %d exit\n", ret);
- break;
- case PERFORM_RESET_PROTECTION_COMPAT:
- if (p61_dev->gpio_coldreset) {
- NFC_LOG_INFO("PERFORM_RESET_PROTECTION is not required and not supported\n");
- } else {
- NFC_LOG_INFO("PERFORM_RESET_PROTECTION: enter\n");
- ret = nfc_ese_pwr(p61_dev->nfcc_data,
- (arg == 1 ? ESE_RST_PROT_EN : ESE_RST_PROT_DIS));
- NFC_LOG_INFO("PERFORM_RESET_PROTECTION ret: %d exit\n", ret);
- }
- break;
- case ESE_SET_TRUSTED_ACCESS:
- NFC_LOG_INFO("Enter %s: TRUSTED access enabled=%lu\n", __func__, arg);
- #if !IS_ENABLED(CONFIG_SAMSUNG_NFC)
- if (arg == 1) {
- NFC_LOG_INFO("ESE_SET_TRUSTED_ACCESS: enter Enabling\n");
- gpio_set_value(p61_dev->trusted_ese_gpio, 1);
- NFC_LOG_INFO("ESE_SET_TRUSTED_ACCESS ret: exit\n");
- } else if (arg == 0) {
- NFC_LOG_INFO("ESE_SET_TRUSTED_ACCESS: enter Disabling\n");
- gpio_set_value(p61_dev->trusted_ese_gpio, 0);
- NFC_LOG_INFO("ESE_SET_TRUSTED_ACCESS ret: exit\n");
- }
- #endif
- break;
- default:
- NFC_LOG_INFO("%s: no matching ioctl!\n", __func__);
- ret = -EINVAL;
- }
- P61_DBG_MSG(KERN_ALERT "%s %u arg = %lu\n", __func__, cmd, arg);
- return ret;
- }
- #else
- static long p61_dev_compat_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg)
- {
- int ret = 0;
- arg = (compat_u64)arg;
- NFC_LOG_INFO(KERN_ALERT "%s-Enter %u arg = %ld\n", __func__, cmd, arg);
- NFC_LOG_DBG("%s: cmd = %x arg = %zx\n", __func__, cmd, arg);
- ret = p61_dev_ioctl(filp, cmd, arg);
- return ret;
- }
- #endif
- #endif
- /**
- * \ingroup spi_driver
- * \brief Write data to P61 on SPI
- *
- * \param[in] struct file *
- * \param[in] const char *
- * \param[in] size_t
- * \param[in] loff_t *
- *
- * \retval data size
- *
- */
- static ssize_t p61_dev_write(struct file *filp, const char *buf, size_t count,
- loff_t * offset)
- {
- int ret = -1;
- struct p61_dev *p61_dev;
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- unsigned char *tx_buffer;
- #else
- unsigned char tx_buffer[MAX_BUFFER_SIZE];
- #endif
- P61_DBG_MSG(KERN_ALERT "p61_dev_write -Enter count %zu\n", count);
- p61_dev = filp->private_data;
- mutex_lock(&p61_dev->write_mutex);
- if (count > MAX_BUFFER_SIZE)
- count = MAX_BUFFER_SIZE;
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- tx_buffer = p61_dev->w_buf;
- memset(&tx_buffer[0], 0, MAX_BUFFER_SIZE);
- #else
- memset(&tx_buffer[0], 0, sizeof(tx_buffer));
- #endif
- if (copy_from_user(&tx_buffer[0], &buf[0], count)) {
- NFC_LOG_ERR("%s: failed to copy from user space\n", __func__);
- mutex_unlock(&p61_dev->write_mutex);
- return -EFAULT;
- }
- /* Write data */
- ret = spi_write(p61_dev->spi, &tx_buffer[0], count);
- if (ret < 0) {
- NFC_LOG_ERR("%s: spi_write fail %d\n", __func__, ret);
- ret = -EIO;
- } else {
- ret = count;
- }
- mutex_unlock(&p61_dev->write_mutex);
- NFC_LOG_REC("%s ret %d- Exit\n", __func__, ret);
- return ret;
- }
- #ifdef P61_IRQ_ENABLE
- /**
- * \ingroup spi_driver
- * \brief To disable IRQ
- *
- * \param[in] struct p61_dev *
- *
- * \retval void
- *
- */
- static void p61_disable_irq(struct p61_dev *p61_dev)
- {
- unsigned long flags;
- P61_DBG_MSG("Entry : %s\n", __func__);
- spin_lock_irqsave(&p61_dev->irq_enabled_lock, flags);
- if (p61_dev->irq_enabled) {
- disable_irq_nosync(p61_dev->spi->irq);
- p61_dev->irq_enabled = false;
- }
- spin_unlock_irqrestore(&p61_dev->irq_enabled_lock, flags);
- P61_DBG_MSG("Exit : %s\n", __func__);
- }
- /**
- * \ingroup spi_driver
- * \brief Will get called when interrupt line asserted from P61
- *
- * \param[in] int
- * \param[in] void *
- *
- * \retval IRQ handle
- *
- */
- static irqreturn_t p61_dev_irq_handler(int irq, void *dev_id)
- {
- struct p61_dev *p61_dev = dev_id;
- P61_DBG_MSG("Entry : %s\n", __func__);
- p61_disable_irq(p61_dev);
- /* Wake up waiting readers */
- wake_up(&p61_dev->read_wq);
- P61_DBG_MSG("Exit : %s\n", __func__);
- return IRQ_HANDLED;
- }
- #endif
- /**
- * \ingroup spi_driver
- * \brief Used to read data from P61 in Poll/interrupt mode configured using ioctl call
- *
- * \param[in] struct file *
- * \param[in] char *
- * \param[in] size_t
- * \param[in] loff_t *
- *
- * \retval read size
- *
- */
- static ssize_t p61_dev_read(struct file *filp, char *buf, size_t count,
- loff_t * offset)
- {
- int ret = -EIO;
- struct p61_dev *p61_dev = filp->private_data;
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- unsigned char *rx_buffer = p61_dev->r_buf;
- #else
- unsigned char rx_buffer[MAX_BUFFER_SIZE];
- #endif
- NFC_LOG_REC("%s count %zu - Enter\n", __func__, count);
- mutex_lock(&p61_dev->read_mutex);
- if (count > MAX_BUFFER_SIZE) {
- count = MAX_BUFFER_SIZE;
- }
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- memset(&rx_buffer[0], 0x00, MAX_BUFFER_SIZE);
- #else
- memset(&rx_buffer[0], 0x00, sizeof(rx_buffer));
- #endif
- if (p61_dev->enable_poll_mode) {
- NFC_LOG_REC("%s Poll Mode Enabled\n", __func__);
- NFC_LOG_REC("SPI_READ returned %zu\n", count);
- ret = spi_read(p61_dev->spi, (void *)&rx_buffer[0], count);
- if (0 > ret) {
- NFC_LOG_ERR("spi_read failed [SOF]\n");
- goto fail;
- }
- } else {
- #ifdef P61_IRQ_ENABLE
- NFC_LOG_REC("%s Interrupt Mode Enabled\n", __func__);
- if (!gpio_get_value(p61_dev->irq_gpio)) {
- if (filp->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
- goto fail;
- }
- while (1) {
- NFC_LOG_REC("%s waiting for interrupt\n", __func__);
- p61_dev->irq_enabled = true;
- enable_irq(p61_dev->spi->irq);
- ret = wait_event_interruptible(p61_dev->read_wq, !p61_dev->irq_enabled);
- p61_disable_irq(p61_dev);
- if (ret) {
- NFC_LOG_ERR("wait_event_interruptible() : Failed\n");
- goto fail;
- }
- if (gpio_get_value(p61_dev->irq_gpio))
- break;
- NFC_LOG_ERR("%s: spurious interrupt detected\n", __func__);
- }
- }
- #else
- NFC_LOG_REC(" %s P61_IRQ_ENABLE not Enabled\n", __func__);
- #endif
- ret = spi_read(p61_dev->spi, (void *)&rx_buffer[0], count);
- if (0 > ret) {
- NFC_LOG_ERR("SPI_READ returned 0x%x\n", ret);
- ret = -EIO;
- goto fail;
- }
- }
- NFC_LOG_REC("total_count = %zu\n", count);
- if (copy_to_user(buf, &rx_buffer[0], count)) {
- NFC_LOG_ERR("%s : failed to copy to user space\n", __func__);
- ret = -EFAULT;
- goto fail;
- }
- NFC_LOG_REC("%s ret %d Exit\n", __func__, ret);
- NFC_LOG_REC("%s ret %d Exit\n", __func__, rx_buffer[0]);
- mutex_unlock(&p61_dev->read_mutex);
- return ret;
- fail:
- NFC_LOG_ERR("Error %s ret %d Exit\n", __func__, ret);
- mutex_unlock(&p61_dev->read_mutex);
- return ret;
- }
- /**
- * \ingroup spi_driver
- * \brief It will configure the GPIOs required for soft reset, read interrupt & regulated power supply to P61.
- *
- * \param[in] struct p61_spi_platform_data *
- * \param[in] struct p61_dev *
- * \param[in] struct spi_device *
- *
- * \retval 0 if ok.
- *
- */
- #if !IS_ENABLED(CONFIG_SAMSUNG_NFC)
- static int p61_hw_setup(struct p61_spi_platform_data *platform_data,
- struct p61_dev *p61_dev, struct spi_device *spi)
- {
- int ret = -1;
- NFC_LOG_INFO("Entry : %s\n", __func__);
- #ifdef P61_IRQ_ENABLE
- ret = gpio_request(platform_data->irq_gpio, "p61 irq");
- if (ret < 0) {
- NFC_LOG_ERR("gpio request failed gpio = 0x%x\n", platform_data->irq_gpio);
- goto fail;
- }
- ret = gpio_direction_input(platform_data->irq_gpio);
- if (ret < 0) {
- NFC_LOG_ERR("gpio request failed gpio = 0x%x\n", platform_data->irq_gpio);
- goto fail_irq;
- }
- #endif
- #ifdef P61_HARD_RESET
- /* RC : platform specific settings need to be declare */
- #if !DRAGON_P61
- p61_regulator = regulator_get(&spi->dev, "vaux3");
- #else
- p61_regulator = regulator_get(&spi->dev, "8941_l18");
- #endif
- if (IS_ERR(p61_regulator)) {
- ret = PTR_ERR(p61_regulator);
- #if !DRAGON_P61
- NFC_LOG_ERR(" Error to get vaux3 (error code) = %d\n", ret);
- #else
- NFC_LOG_ERR(" Error to get 8941_l18 (error code) = %d\n", ret);
- #endif
- return -ENODEV;
- } else {
- NFC_LOG_INFO("successfully got regulator\n");
- }
- ret = regulator_set_voltage(p61_regulator, 1800000, 1800000);
- if (ret != 0) {
- NFC_LOG_ERR("Error setting the regulator voltage %d\n", ret);
- regulator_put(p61_regulator);
- return ret;
- } else {
- regulator_enable(p61_regulator);
- NFC_LOG_INFO("successfully set regulator voltage\n");
- }
- ret = gpio_request(platform_data->rst_gpio, "p61 reset");
- if (ret < 0) {
- NFC_LOG_ERR("gpio reset request failed = 0x%x\n", platform_data->rst_gpio);
- goto fail_gpio;
- }
- /*soft reset gpio is set to default high */
- ret = gpio_direction_output(platform_data->rst_gpio, 1);
- if (ret < 0) {
- NFC_LOG_ERR("gpio rst request failed gpio = 0x%x\n", platform_data->rst_gpio);
- goto fail_gpio;
- }
- #endif
- ret = gpio_request( platform_data->trusted_ese_gpio, "Trusted SE switch");
- if (ret < 0) {
- NFC_LOG_ERR("gpio reset request failed = 0x%x\n",
- platform_data->trusted_ese_gpio);
- gpio_free(platform_data->trusted_ese_gpio);
- NFC_LOG_ERR("%s failed\n", __func__);
- return ret;
- }
- ret = gpio_direction_output(platform_data->trusted_ese_gpio,0);
- if (ret < 0) {
- NFC_LOG_ERR("gpio rst request failed gpio = 0x%x\n",
- platform_data->trusted_ese_gpio);
- gpio_free(platform_data->trusted_ese_gpio);
- NFC_LOG_ERR("%s failed\n, __func__");
- return ret;
- }
- ret = ese_reset_gpio_setup(platform_data);
- if (ret < 0) {
- P61_ERR_MSG("Failed to setup ese reset gpio");
- goto fail;
- }
- ret = 0;
- NFC_LOG_INFO("Exit : %s\n", __func__);
- return ret;
- #ifdef P61_IRQ_ENABLE
- fail_irq:
- gpio_free(platform_data->irq_gpio);
- #endif
- fail:
- NFC_LOG_ERR("p61_hw_setup failed\n");
- return ret;
- }
- #endif
- /**
- * \ingroup spi_driver
- * \brief Set the P61 device specific context for future use.
- *
- * \param[in] struct spi_device *
- * \param[in] void *
- *
- * \retval void
- *
- */
- static inline void p61_set_data(struct spi_device *spi, void *data)
- {
- dev_set_drvdata(&spi->dev, data);
- }
- /**
- * \ingroup spi_driver
- * \brief Get the P61 device specific context.
- *
- * \param[in] const struct spi_device *
- *
- * \retval Device Parameters
- *
- */
- static inline void *p61_get_data(const struct spi_device *spi)
- {
- return dev_get_drvdata(&spi->dev);
- }
- /* possible fops on the p61 device */
- static const struct file_operations p61_dev_fops = {
- .owner = THIS_MODULE,
- .read = p61_dev_read,
- .write = p61_dev_write,
- .open = p61_dev_open,
- .release = p61_dev_release,
- .unlocked_ioctl = p61_dev_ioctl,
- #ifdef CONFIG_COMPAT
- .compat_ioctl = p61_dev_compat_ioctl,
- #endif
- };
- #if DRAGON_P61 || IS_ENABLED(CONFIG_SAMSUNG_NFC)
- static int p61_parse_dt(struct device *dev, struct p61_spi_platform_data *data)
- {
- struct device_node *np = dev->of_node;
- int errorno = 0;
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- int ese_det_gpio;
- const char *ap_str;
- int ret;
- ese_det_gpio = of_get_named_gpio(np, "ese-det-gpio", 0);
- if (!gpio_is_valid(ese_det_gpio)) {
- NFC_LOG_INFO("%s: ese-det-gpio is not set\n", __func__);
- } else {
- ret = gpio_request(ese_det_gpio, "ese_det_gpio");
- if (ret < 0)
- NFC_LOG_ERR("%s failed to get gpio ese_det_gpio\n", __func__);
- gpio_direction_input(ese_det_gpio);
- if (!gpio_get_value(ese_det_gpio)) {
- NFC_LOG_INFO("%s: ese is not supported\n", __func__);
- return -ENODEV;
- }
- NFC_LOG_INFO("%s: ese is supported\n", __func__);
- }
- if (!of_property_read_string(np, "p61,ap_vendor", &ap_str)) {
- if (!strcmp(ap_str, "slsi"))
- data->ap_vendor = AP_VENDOR_SLSI;
- else if (!strcmp(ap_str, "qct") || !strcmp(ap_str, "qualcomm"))
- data->ap_vendor = AP_VENDOR_QCT;
- else if (!strcmp(ap_str, "mtk"))
- data->ap_vendor = AP_VENDOR_MTK;
- NFC_LOG_INFO("AP vendor is %d\n", data->ap_vendor);
- } else {
- NFC_LOG_INFO("AP vendor is not set\n");
- }
- data->gpio_coldreset = of_property_read_bool(np, "p61,gpio_coldreset_support");
- if (data->gpio_coldreset) {
- NFC_LOG_INFO("gpio coldreset supports\n");
- data->rst_gpio = of_get_named_gpio(np, "p61,gpio-rst", 0);
- if ((!gpio_is_valid(data->rst_gpio)))
- return -EINVAL;
- }
- #else
- data->irq_gpio = of_get_named_gpio(np, "nxp,p61-irq", 0);
- if ((!gpio_is_valid(data->irq_gpio)))
- return -EINVAL;
- data->rst_gpio = of_get_named_gpio(np, "nxp,p61-rst", 0);
- if ((!gpio_is_valid(data->rst_gpio)))
- return -EINVAL;
- data->trusted_ese_gpio = of_get_named_gpio(np, "nxp,trusted-se", 0);
- if ((!gpio_is_valid(data->trusted_ese_gpio)))
- return -EINVAL;
- NFC_LOG_INFO("%s: %d, %d, %d %d\n", __func__, data->irq_gpio, data->rst_gpio,
- data->trusted_ese_gpio, errorno);
- #endif
- return errorno;
- }
- #endif
- #if IS_ENABLED(CONFIG_SPI_MSM_GENI)
- #if IS_ENABLED(CONFIG_MSM_GENI_SE)
- /*
- * eSE driver can't access spi_geni_master structure because it's defined in drivers/spi/spi-msm-geni.c file.
- * so, we need a logic to search se_geni_rsc in "void *spi_geni_master".
- */
- struct se_geni_rsc *p61_find_spi_src(struct p61_dev *p61_dev, void *spi_geni_master)
- {
- char *offset = spi_geni_master;
- struct se_geni_rsc *rsc;
- int i;
- int max_addr_cnt = 250;
- for (i = 0; i < max_addr_cnt; i++) {
- rsc = (struct se_geni_rsc *)offset;
- if (rsc->geni_gpio_active == p61_dev->pinctrl_state[P61_PIN_CTRL_DEFAULT]) {
- NFC_LOG_INFO("%s, found se_geni_rsc!\n", __func__);
- return rsc;
- }
- offset++;
- }
- /* Check if spi_geni_master structure member which defined in spi-msm-geni.c file is changed or not when failed to find se_geni_src. */
- NFC_LOG_ERR("%s, failed to find se_geni_rsc!\n", __func__);
- return 0;
- }
- #else
- /* CONFIG_QCOM_GENI_SE */
- struct qc_spi_pinctrl {
- struct pinctrl *geni_pinctrl;
- struct pinctrl_state *geni_gpio_active;
- struct pinctrl_state *geni_gpio_sleep;
- };
- struct qc_spi_pinctrl *p61_find_spi_src(struct p61_dev *p61_dev, void *spi_geni_master)
- {
- char *offset = spi_geni_master;
- struct qc_spi_pinctrl *spi_pinctrl;
- int i;
- int max_addr_cnt = 250;
- for (i = 0; i < max_addr_cnt; i++) {
- spi_pinctrl = (struct qc_spi_pinctrl *)offset;
- if (spi_pinctrl->geni_pinctrl == p61_dev->pinctrl &&
- spi_pinctrl->geni_gpio_active == p61_dev->pinctrl_state[P61_PIN_CTRL_DEFAULT]) {
- NFC_LOG_INFO("%s, found pinctrl in spi master!\n", __func__);
- return spi_pinctrl;
- }
- offset++;
- }
- NFC_LOG_ERR("%s, failed to find spi pinctrl!\n", __func__);
- return 0;
- }
- #endif
- static void p61_set_spi_bus_pincontrol(struct p61_dev *p61_dev)
- {
- struct spi_master *master;
- void *geni_mas;
- #if IS_ENABLED(CONFIG_MSM_GENI_SE)
- struct se_geni_rsc *spi_pinctrl;
- #else
- struct qc_spi_pinctrl *spi_pinctrl;
- #endif
- static bool called;
- if (!p61_dev || called)
- return;
- if (!p61_dev->pinctrl_state[P61_PIN_CTRL_ACTIVE] || !p61_dev->pinctrl_state[P61_PIN_CTRL_SUSPEND])
- return;
- NFC_LOG_INFO("%s\n", __func__);
- called = true;
- master = platform_get_drvdata(p61_dev->spi_pdev);
- geni_mas = spi_master_get_devdata(master);
- spi_pinctrl = p61_find_spi_src(p61_dev, geni_mas);
- if (spi_pinctrl) {
- spi_pinctrl->geni_gpio_sleep =
- pinctrl_lookup_state(spi_pinctrl->geni_pinctrl,
- p61_pinctrl_name[P61_PIN_CTRL_SUSPEND]);
- spi_pinctrl->geni_gpio_active =
- pinctrl_lookup_state(spi_pinctrl->geni_pinctrl,
- p61_pinctrl_name[P61_PIN_CTRL_ACTIVE]);
- }
- }
- #endif
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- static void p61_parse_pinctrl_dt(struct device *dev, struct p61_dev *p61_dev)
- {
- struct device_node *spi_dev_node;
- struct device_node *np = dev->of_node;
- struct platform_device *spi_pdev;
- struct pinctrl_state *tmp_pinctrl;
- int i;
- spi_dev_node = of_get_parent(np);
- if (IS_ERR_OR_NULL(spi_dev_node)) {
- NFC_LOG_INFO("no spi pinctrl\n");
- return;
- }
- spi_pdev = of_find_device_by_node(spi_dev_node);
- if (!spi_pdev) {
- NFC_LOG_ERR("finding spi_dev failed\n");
- return;
- }
- p61_dev->pinctrl = devm_pinctrl_get(&spi_pdev->dev);
- if (IS_ERR(p61_dev->pinctrl)) {
- NFC_LOG_ERR("pinctrl_get failed\n");
- return;
- }
- for (i = 0; i < P61_PIN_CTRL_MAX; i++) {
- tmp_pinctrl = pinctrl_lookup_state(p61_dev->pinctrl, p61_pinctrl_name[i]);
- if (!IS_ERR(tmp_pinctrl)) {
- NFC_LOG_INFO("pinctrl[%s] found\n", p61_pinctrl_name[i]);
- p61_dev->pinctrl_state[i] = tmp_pinctrl;
- }
- }
- p61_dev->spi_pdev = spi_pdev;
- #if IS_ENABLED(CONFIG_SPI_MSM_GENI)
- p61_set_spi_bus_pincontrol(p61_dev);
- #endif
- if (nfc_check_pvdd_status())
- ese_set_spi_pinctrl_for_ese_off(p61_dev);
- }
- void ese_set_spi_pinctrl_for_ese_off(void *p61)
- {
- struct p61_dev *p61_dev = (struct p61_dev *)p61;
- if (!p61_dev)
- p61_dev = g_p61_dev;
- if (!p61_dev) {
- pr_err("%s: spi probe is not called\n", __func__);
- return;
- }
- p61_pinctrl_select(p61_dev, P61_PIN_CTRL_ESE_OFF); /* for LSI AP */
- p61_pinctrl_select(p61_dev, P61_PIN_CTRL_SUSPEND); /* for QC AP */
- }
- #endif
- /**
- * \ingroup spi_driver
- * \brief To probe for P61 SPI interface. If found initialize the SPI clock, bit rate & SPI mode.
- * It will create the dev entry (P61) for user space.
- *
- * \param[in] struct spi_device *
- *
- * \retval 0 if ok.
- *
- */
- static int p61_probe(struct spi_device *spi)
- {
- int ret = -1;
- struct p61_spi_platform_data *platform_data = NULL;
- struct p61_spi_platform_data platform_data1;
- struct p61_dev *p61_dev = NULL;
- unsigned int max_speed_hz;
- struct device_node *np = spi->dev.of_node;
- #ifdef P61_IRQ_ENABLE
- unsigned int irq_flags;
- #endif
- #ifdef CONFIG_SEC_NFC_LOGGER
- nfc_logger_init();
- nfc_logger_set_max_count(-1);
- #endif
- NFC_LOG_INFO("%s chip select : %d , bus number = %d\n", __func__,
- spi->chip_select, spi->master->bus_num);
- memset(&platform_data1, 0x00, sizeof(struct p61_spi_platform_data));
- #if !DRAGON_P61 && !IS_ENABLED(CONFIG_SAMSUNG_NFC)
- platform_data = spi->dev.platform_data;
- if (platform_data == NULL) {
- /* RC : rename the platformdata1 name */
- /* TBD: This is only for Panda as we are passing NULL for platform data */
- NFC_LOG_ERR("%s : p61 probe fail\n", __func__);
- platform_data1.irq_gpio = P61_IRQ;
- platform_data1.rst_gpio = P61_RST;
- platform_data = &platform_data1;
- NFC_LOG_ERR("%s : p61 probe fail1\n", __func__);
- //return -ENODEV;
- }
- #else
- ret = p61_parse_dt(&spi->dev, &platform_data1);
- if (ret) {
- NFC_LOG_ERR("%s - Failed to parse DT\n", __func__);
- goto err_exit;
- }
- platform_data = &platform_data1;
- #endif
- p61_dev = kzalloc(sizeof(*p61_dev), GFP_KERNEL);
- if (p61_dev == NULL) {
- NFC_LOG_ERR("failed to allocate memory for module data\n");
- ret = -ENOMEM;
- goto err_exit;
- }
- #if !IS_ENABLED(CONFIG_SAMSUNG_NFC)
- ret = p61_hw_setup(platform_data, p61_dev, spi);
- if (ret < 0) {
- NFC_LOG_ERR("Failed to p61_enable_P61_IRQ_ENABLE\n");
- goto err_exit0;
- }
- #endif
- if (platform_data->gpio_coldreset) {
- ret = ese_reset_gpio_setup(platform_data);
- if (ret < 0) {
- P61_ERR_MSG("Failed to setup ese reset gpio");
- goto err_exit0;
- }
- }
- /* gpio cold reset doesn't work. so, set gpio coldreset to false to use i2c cold reset */
- platform_data->gpio_coldreset = false;
- spi->bits_per_word = 8;
- spi->mode = SPI_MODE_0;
- ret = of_property_read_u32(np, "spi-max-frequency", &max_speed_hz);
- if (ret < 0) {
- NFC_LOG_ERR("%s: There's no spi-max-frequency property\n", __func__);
- goto err_exit0;
- }
- spi->max_speed_hz = max_speed_hz;
- NFC_LOG_INFO("%s : spi max_speed_hz = %d\n", __func__, spi->max_speed_hz);
- //spi->chip_select = SPI_NO_CS;
- ret = spi_setup(spi);
- if (ret < 0) {
- NFC_LOG_ERR("failed to do spi_setup()\n");
- goto err_exit0;
- }
- p61_dev->spi = spi;
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- p61_parse_pinctrl_dt(&spi->dev, p61_dev);
- #endif
- #ifndef CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE
- p61_dev->p61_device.minor = MISC_DYNAMIC_MINOR;
- p61_dev->p61_device.name = "p61";
- p61_dev->p61_device.fops = &p61_dev_fops;
- p61_dev->p61_device.parent = &spi->dev;
- #endif
- p61_dev->irq_gpio = platform_data->irq_gpio;
- p61_dev->rst_gpio = platform_data->rst_gpio;
- p61_dev->trusted_ese_gpio = platform_data->trusted_ese_gpio;
- p61_dev->gpio_coldreset = platform_data->gpio_coldreset;
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- p61_dev->ap_vendor = platform_data->ap_vendor;
- #else
- p61_dev->trusted_ese_gpio = platform_data->trusted_ese_gpio;
- #endif
- p61_dev->ese_spi_transition_state = ESE_SPI_IDLE;
- dev_set_drvdata(&spi->dev, p61_dev);
- /* init mutex and queues */
- init_waitqueue_head(&p61_dev->read_wq);
- mutex_init(&p61_dev->read_mutex);
- mutex_init(&p61_dev->write_mutex);
- if (p61_dev->gpio_coldreset)
- ese_reset_init();
- #ifdef P61_IRQ_ENABLE
- spin_lock_init(&p61_dev->irq_enabled_lock);
- #endif
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- p61_dev->nfc_node = of_parse_phandle(np, "nxp,nfcc", 0);
- if (!p61_dev->nfc_node) {
- NFC_LOG_ERR("%s: nxp,nfcc invalid or missing in device tree\n", __func__);
- goto err_exit0;
- }
- #else
- ret = of_property_read_string(np, "nxp,nfcc", &p61_dev->nfcc_name);
- if (ret < 0) {
- NFC_LOG_ERR("%s: nxp,nfcc invalid or missing in device tree (%d)\n",
- __func__, ret);
- goto err_exit0;
- }
- NFC_LOG_INFO("%s: device tree set '%s' as eSE power controller\n",
- __func__, p61_dev->nfcc_name);
- #endif
- #ifndef CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE
- ret = misc_register(&p61_dev->p61_device);
- if (ret < 0) {
- NFC_LOG_ERR("misc_register failed! %d\n", ret);
- goto err_exit0;
- }
- #endif
- #ifdef P61_IRQ_ENABLE
- p61_dev->spi->irq = gpio_to_irq(platform_data->irq_gpio);
- if (p61_dev->spi->irq < 0) {
- NFC_LOG_ERR("gpio_to_irq request failed gpio = 0x%x\n",
- platform_data->irq_gpio);
- goto err_exit1;
- }
- /* request irq. the irq is set whenever the chip has data available
- * for reading. it is cleared when all data has been read.
- */
- p61_dev->irq_enabled = true;
- irq_flags = IRQF_TRIGGER_RISING | IRQF_ONESHOT;
- ret = request_irq(p61_dev->spi->irq, p61_dev_irq_handler, irq_flags,
- p61_dev->p61_device.name, p61_dev);
- if (ret) {
- NFC_LOG_ERR("request_irq failed\n");
- goto err_exit1;
- }
- p61_disable_irq(p61_dev);
- #endif
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- p61_dev->r_buf = kzalloc(sizeof(unsigned char) * MAX_BUFFER_SIZE, GFP_KERNEL);
- if (p61_dev->r_buf == NULL) {
- NFC_LOG_ERR("failed to allocate for spi read buffer\n");
- ret = -ENOMEM;
- goto err_exit2;
- }
- p61_dev->w_buf = kzalloc(sizeof(unsigned char) * MAX_BUFFER_SIZE, GFP_KERNEL);
- if (p61_dev->w_buf == NULL) {
- NFC_LOG_ERR("failed to allocate for spi write buffer\n");
- ret = -ENOMEM;
- goto err_exit3;
- }
- wake_lock_init(&p61_dev->ese_lock, WAKE_LOCK_SUSPEND, "ese_lock");
- #if IS_ENABLED(CONFIG_SPI_MSM_GENI)
- INIT_DELAYED_WORK(&p61_dev->spi_release_work, p61_spi_release_work);
- wake_lock_init(&p61_dev->spi_release_wakelock, WAKE_LOCK_SUSPEND, "ese_spi_wake_lock");
- #endif
- #endif
- p61_dev->enable_poll_mode = 0; /* Default IRQ read mode */
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- g_p61_dev = p61_dev;
- #endif
- NFC_LOG_INFO("Exit : %s\n", __func__);
- return ret;
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- err_exit3:
- kfree(p61_dev->r_buf);
- err_exit2:
- #endif
- #ifdef P61_IRQ_ENABLE
- err_exit1:
- #ifndef CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE
- misc_deregister(&p61_dev->p61_device);
- #endif
- #endif
- err_exit0:
- mutex_destroy(&p61_dev->read_mutex);
- mutex_destroy(&p61_dev->write_mutex);
- if (p61_dev->gpio_coldreset)
- ese_reset_deinit();
- if (p61_dev != NULL)
- kfree(p61_dev);
- err_exit:
- NFC_LOG_ERR("ERROR: Exit : %s ret %d\n", __func__, ret);
- return ret;
- }
- #ifdef CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE
- static struct miscdevice p61_misc_device = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "p61",
- .fops = &p61_dev_fops,
- };
- static int p61_platform_probe(struct platform_device *pdev)
- {
- int ret = -1;
- ret = misc_register(&p61_misc_device);
- if (ret < 0)
- NFC_LOG_ERR("misc_register failed! %d\n", ret);
- NFC_LOG_INFO("%s: finished...\n", __func__);
- return 0;
- }
- static int p61_platform_remove(struct platform_device *pdev)
- {
- NFC_LOG_INFO("Entry : %s\n", __func__);
- return 0;
- }
- static const struct of_device_id p61_secure_match_table[] = {
- { .compatible = "p61_platform",},
- {},
- };
- static struct platform_driver p61_platform_driver = {
- .driver = {
- .name = "p61_platform",
- .owner = THIS_MODULE,
- #ifdef CONFIG_OF
- .of_match_table = p61_secure_match_table,
- #endif
- },
- .probe = p61_platform_probe,
- .remove = p61_platform_remove,
- };
- #endif /* CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE */
- /**
- * \ingroup spi_driver
- * \brief Will get called when the device is removed to release the resources.
- *
- * \param[in] struct spi_device
- *
- * \retval 0 if ok.
- *
- */
- #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- static int p61_remove(struct spi_device *spi)
- #else
- static void p61_remove(struct spi_device *spi)
- #endif
- {
- struct p61_dev *p61_dev = p61_get_data(spi);
- P61_DBG_MSG("Entry : %s\n", __func__);
- #ifdef P61_HARD_RESET
- if (p61_regulator != NULL) {
- regulator_disable(p61_regulator);
- regulator_put(p61_regulator);
- } else {
- NFC_LOG_ERR("ERROR %s p61_regulator not enabled\n", __func__);
- }
- #endif
- if (p61_dev != NULL) {
- gpio_free(p61_dev->rst_gpio);
- #ifdef P61_IRQ_ENABLE
- free_irq(p61_dev->spi->irq, p61_dev);
- gpio_free(p61_dev->irq_gpio);
- #endif
- #if !IS_ENABLED(CONFIG_SAMSUNG_NFC)
- if (gpio_is_valid(p61_dev->trusted_ese_gpio)) {
- gpio_free(p61_dev->trusted_ese_gpio);
- }
- #endif
- mutex_destroy(&p61_dev->read_mutex);
- #ifdef CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE
- misc_deregister(&p61_misc_device);
- #else
- misc_deregister(&p61_dev->p61_device);
- #endif
- if (p61_dev->gpio_coldreset)
- ese_reset_deinit();
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- wake_lock_destroy(&p61_dev->ese_lock);
- #endif
- kfree(p61_dev);
- }
- P61_DBG_MSG("Exit : %s\n", __func__);
- #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- return 0;
- #endif
- }
- #if DRAGON_P61
- static struct of_device_id p61_dt_match[] = {
- {
- .compatible = "p61",
- },
- {}
- };
- #endif
- static struct spi_driver p61_driver = {
- .driver = {
- .name = "p61",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- #if DRAGON_P61
- .of_match_table = p61_dt_match,
- #endif
- },
- .probe = p61_probe,
- .remove = (p61_remove),
- };
- /**
- * \ingroup spi_driver
- * \brief Module init interface
- *
- * \param[in] void
- *
- * \retval handle
- *
- */
- #if IS_MODULE(CONFIG_SAMSUNG_NFC)
- int p61_dev_init(void)
- {
- int ret;
- debug_level = P61_DEBUG_OFF;
- P61_DBG_MSG("Entry : %s\n", __func__);
- #ifdef CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE
- ret = platform_driver_register(&p61_platform_driver);
- NFC_LOG_INFO("%s: platform_driver_register, ret %d\n", __func__, ret);
- #endif
- ret = spi_register_driver(&p61_driver);
- return ret;
- }
- EXPORT_SYMBOL(p61_dev_init);
- void p61_dev_exit(void)
- {
- P61_DBG_MSG("Entry : %s\n", __func__);
- #ifdef CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE
- platform_driver_unregister(&p61_platform_driver);
- #endif
- spi_unregister_driver(&p61_driver);
- }
- EXPORT_SYMBOL(p61_dev_exit);
- #else
- static int __init p61_dev_init(void)
- {
- int ret;
- debug_level = P61_DEBUG_OFF;
- P61_DBG_MSG("Entry : %s\n", __func__);
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- if (nfc_get_lpcharge() == LPM_TRUE)
- return 0;
- #endif
- #ifdef CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE
- ret = platform_driver_register(&p61_platform_driver);
- NFC_LOG_INFO("%s: platform_driver_register, ret %d\n", __func__, ret);
- #endif
- ret = spi_register_driver(&p61_driver);
- return ret;
- }
- module_init(p61_dev_init);
- /**
- * \ingroup spi_driver
- * \brief Module exit interface
- *
- * \param[in] void
- *
- * \retval void
- *
- */
- static void __exit p61_dev_exit(void)
- {
- P61_DBG_MSG("Entry : %s\n", __func__);
- #if IS_ENABLED(CONFIG_SAMSUNG_NFC)
- if (nfc_get_lpcharge() == LPM_TRUE)
- return;
- #endif
- #ifdef CONFIG_MAKE_NODE_USING_PLATFORM_DEVICE
- platform_driver_unregister(&p61_platform_driver);
- #endif
- spi_unregister_driver(&p61_driver);
- }
- module_exit(p61_dev_exit);
- MODULE_ALIAS("spi:p61");
- MODULE_AUTHOR("BHUPENDRA PAWAR");
- MODULE_DESCRIPTION("NXP P61 SPI driver");
- MODULE_LICENSE("GPL");
- #endif
- /** @} */
|