siyahkernel / drivers / misc / pn544.c
1 /* 2 * Copyright (C) 2010 Trusted Logic S.A. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * 18 */
19 20 #include
38 39 #define MAX_BUFFER_SIZE 512
40 #define MAX_LLC_FRAME_SIZE 0x20 41 #define MAX_TRY_I2C_READ 10
42 43 #define NFC_DEBUG 0
44 45 struct pn544_dev { 46 wait_queue_head_t read_wq; 47 struct mutex read_mutex; 48 struct i2c_client *client; 49 struct miscdevice pn544_device; 50 unsigned int ven_gpio; 51 unsigned int firm_gpio; 52 unsigned int irq_gpio; 53 bool irq_enabled; 54 spinlock_t irq_enabled_lock; 55 };
56 57 bool do_reading;
58 59 static void pn544_disable_irq(struct pn544_dev *pn544_dev) 60 { 61 unsigned long flags;
62 63 spin_lock_irqsave(&pn544_dev->irq_enabled_lock, flags); 64 if (pn544_dev->irq_enabled) { 65 disable_irq_nosync(pn544_dev->client->irq); 66 pn544_dev->irq_enabled = false; 67 } 68 spin_unlock_irqrestore(&pn544_dev->irq_enabled_lock, flags); 69 }
70 71 static irqreturn_t pn544_dev_irq_handler(int irq, void *dev_id) 72 { 73 struct pn544_dev *pn544_dev = dev_id;
74 75 if (!gpio_get_value(pn544_dev->irq_gpio)) 76 return IRQ_HANDLED;
77 78 pn544_disable_irq(pn544_dev); 79 /* Wake up waiting readers */ 80 wake_up(&pn544_dev->read_wq);
81 do_reading=1;
82 83 #if NFC_DEBUG 84 pr_info(\); 85 #endif
86 87 return IRQ_HANDLED; 88 }
89 90 static ssize_t pn544_dev_read(struct file *filp, char __user *buf, 91 size_t count, loff_t *offset) 92 { 93 struct pn544_dev *pn544_dev = filp->private_data; 94 char tmp[MAX_BUFFER_SIZE]; 95 int ret; 96 char datasizelength = 1; 97 char datasize = 0; 98 char readingWatchdog = 0;
99 100 101 if (count > MAX_BUFFER_SIZE) 102 count = MAX_BUFFER_SIZE;
103 104 pr_debug(\, __func__, 105 count,gpio_get_value(pn544_dev->irq_gpio)?\:\);
106 107 #if NFC_DEBUG 108 pr_info(\); 109 #endif
110 111 mutex_lock(&pn544_dev->read_mutex);
112 113 wait_irq :
114 115 if(!gpio_get_value(pn544_dev->irq_gpio)) {
116 117 if (filp->f_flags & O_NONBLOCK) { 118 pr_info(\, __func__); 119 ret = -EAGAIN; 120 goto fail; 121 }
122 123 pn544_dev->irq_enabled = true; 124 do_reading=0; 125 enable_irq(pn544_dev->client->irq);
126 127 ret = wait_event_interruptible(pn544_dev->read_wq,do_reading); 128 /* gpio_get_value(pn544_dev->irq_gpio)); */ 129 /* pr_info(\ 130 pn544_disable_irq(pn544_dev);
131 132 #if NFC_DEBUG 133 pr_info(\ h\\n\); 134 #endif
135 136 if (ret) 137 goto fail; 138 } 139 /* Read data */
140 141 if (count == 1)/*Normal mode*/ 142 { 143 ret = i2c_master_recv(pn544_dev->client, tmp, datasizelength);
144 145 if (copy_to_user(buf, tmp, datasizelength)) { 146 pr_warning(\, __func__)147 return -EFAULT; 148 }
149 150 /*If bad frame is received from pn544, we need to read again after waiting that IR151 down*/ 152 if (MAX_LLC_FRAME_SIZE 159 160 datasize = tmp[0]; 161 162 ret = i2c_master_recv(pn544_dev->client, tmp, datasize); 163 164 mutex_unlock(&pn544_dev->read_mutex); 165 166 if (ret < 0) { 167 pr_err(\, __func__, ret); 168 return ret; 169 } 170 if (ret > datasize+1) { 171 pr_err(\, 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 down*/ 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 __func__, ret); return -EIO; } if (copy_to_user(buf+1, tmp, ret)) { pr_err(\, __func__); return -EFAULT; } //add one more byte for size byte (read on first time) ret++; } else /*download mode*/ { ret = i2c_master_recv(pn544_dev->client, tmp, count); /*If bad frame is received from pn544, we need to read again after waiting that IRif (MAX_LLC_FRAME_SIZE mutex_unlock(&pn544_dev->read_mutex); if (ret < 0) { pr_err(\, __func__, ret); return ret; } if (ret > count) { 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库NXP恩智浦 PN544 driver驱动程序在线全文阅读。
相关推荐: