diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/misc/pn547.c')
-rwxr-xr-x | ANDROID_3.4.5/drivers/misc/pn547.c | 1180 |
1 files changed, 0 insertions, 1180 deletions
diff --git a/ANDROID_3.4.5/drivers/misc/pn547.c b/ANDROID_3.4.5/drivers/misc/pn547.c deleted file mode 100755 index ff819341..00000000 --- a/ANDROID_3.4.5/drivers/misc/pn547.c +++ /dev/null @@ -1,1180 +0,0 @@ -/* - * Copyright (C) 2010 Trusted Logic S.A. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#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/i2c.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/miscdevice.h> -#include <linux/spinlock.h> -#include <linux/nfc/pn544.h> - -#include <mach/wmt_iomux.h> - -#include <mach/hardware.h> -//#include <plat/gpio-core.h> -//#include <plat/gpio-cfg.h> -//#include <plat/gpio-cfg-helpers.h> - - -#undef pr_err -#define pr_err printk -//#define pr_debug printk -//#define pr_warning printk - -#define DRIVER_DESC "NFC driver for PN544" - -#define CLIENT_ADDR 0x28 //0x2b mod 2014-7-10 -#define WMT_PN544_I2C_CHANNEL 0 - -struct i2c_client *pn544_client; -static int g_chip_nr = 7; - -#define MAX_BUFFER_SIZE 512 - -extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); - -struct pn544_dev { - wait_queue_head_t read_wq; - struct mutex read_mutex; - struct i2c_client *client; - struct miscdevice pn544_device; - - - int ven_gpio; - int ven_active; - int ven_on_off; - - int firm_gpio; - int firm_active; - - int irq_gpio; - int irq_active; - - - bool irq_enabled; - spinlock_t irq_enabled_lock; -}; - -//**********************add 2014-7-16 -static int irq_gpio = 0; - -void wmt_clr_int(void) -{ - int num = irq_gpio; - - int reg_shift = 20; - if (num > /*11*/42) - { - return; - } - - if (num < 20) - { - REG32_VAL(__GPIO_BASE+0x0360) = 1<<num; - } - else - { - switch (num) - { - case WMT_PIN_GP5_VDOUT11: - REG32_VAL(__GPIO_BASE+0x0360) = 1<<reg_shift; - break; - case WMT_PIN_GP5_VDOUT12: - REG32_VAL(__GPIO_BASE+0x0360) = 1<<(reg_shift+1); - break; - case WMT_PIN_GP6_VDOUT18: - REG32_VAL(__GPIO_BASE+0x0360) = 1<<(reg_shift+2); - break; - case WMT_PIN_GP6_VDOUT19: - REG32_VAL(__GPIO_BASE+0x0360) = 1<<(reg_shift+3); - break; - case WMT_PIN_GP6_VDOUT20: - REG32_VAL(__GPIO_BASE+0x0360) = 1<<(reg_shift+4); - break; - case WMT_PIN_GP6_VDOUT21: - REG32_VAL(__GPIO_BASE+0x0360) = 1<<(reg_shift+5); - break; - - } - } - //gpio 0-19 vdout11 12 18:21 - //REG32_VAL(__GPIO_BASE+0x0360) = 1<<num; //interrupt status register ,1:active 0:inactive - // write 1:to clear -} - -void wmt_set_irqinput(void) -{ - int num = irq_gpio; - - if (num > /*19*/42) - return; - if (num < 20) - { - REG32_VAL(__GPIO_BASE+0x0040) |= (1<<num); //enable gpio - REG32_VAL(__GPIO_BASE+0x0080) &= ~(1<<num); //set input - } - - //GPIO GP5 Enable Register for VDOUT[15:8] - //GPIO GP6 Enable Register for VDOUT[23:16] - - switch (num) //gpio 0-19 vdout11 12 18:21 -->gpio 31 32 38:41 - { - case WMT_PIN_GP5_VDOUT11: - REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - case WMT_PIN_GP5_VDOUT12: - REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - case WMT_PIN_GP6_VDOUT18: - REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - case WMT_PIN_GP6_VDOUT19: - REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - case WMT_PIN_GP6_VDOUT20: - REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - case WMT_PIN_GP6_VDOUT21: - REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - - } -} - -static void wmt_disable_irqinput(void) -{ - int num = irq_gpio; - - if (num > /*19*/42) - return; - if (num < 20) - { - REG32_VAL(__GPIO_BASE+0x0040) &= ~(1<<num); //enable gpio - REG32_VAL(__GPIO_BASE+0x0080) &= ~(1<<num); //set input - } - - //GPIO GP5 Enable Register for VDOUT[15:8] - //GPIO GP6 Enable Register for VDOUT[23:16] - - switch (num) //gpio 0-19 vdout11 12 18:21 -->gpio 31 32 38:41 - { - case WMT_PIN_GP5_VDOUT11: - REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //disable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - case WMT_PIN_GP5_VDOUT12: - REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - case WMT_PIN_GP6_VDOUT18: - REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - case WMT_PIN_GP6_VDOUT19: - REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - case WMT_PIN_GP6_VDOUT20: - REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - case WMT_PIN_GP6_VDOUT21: - REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //enable gpio - REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input - break; - - } -} - -static void wmt_pullup(void) -{ - int num = irq_gpio; - - if(num >/*11*//*19*/42) - return; - if (num < 20) - { - REG32_VAL(__GPIO_BASE+0x04c0) |= (1<<num); //pull up! - REG32_VAL(__GPIO_BASE+0x0480) |= (1<<num); //enable pull up/down - } - switch (num) - { //vdout11 12 18:21-->gpio 31 32 38:41 - case WMT_PIN_GP5_VDOUT11: - REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up! - REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down - break; - case WMT_PIN_GP5_VDOUT12: - REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up! - REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down - break; - case WMT_PIN_GP6_VDOUT18: - REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up! - REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down - break; - case WMT_PIN_GP6_VDOUT19: - REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up! - REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down - break; - case WMT_PIN_GP6_VDOUT20: - REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up! - REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down - break; - case WMT_PIN_GP6_VDOUT21: - REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up! - REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down - break; - - } -} - -int wmt_set_gpirq(int type) -{ - int shift; - int offset; - unsigned long reg; - int num = irq_gpio; - - if(num >/*11*//*19*/42) - return -1; - //if (num > 9) - //GPIO_PIN_SHARING_SEL_4BYTE_VAL &= ~BIT4; // gpio10,11 as gpio -#if 0 - REG32_VAL(__GPIO_BASE+0x0040) &= ~(1<<num); // gpio disable - REG32_VAL(__GPIO_BASE+0x0080) &= ~(1<<num); //set input -#endif - wmt_disable_irqinput();//replace 2014-8-22 -#if 0 - REG32_VAL(__GPIO_BASE+0x04c0) |= (1<<num); //pull up! - REG32_VAL(__GPIO_BASE+0x0480) |= (1<<num); //enable pull up/down -#endif - wmt_pullup();//replace 2014-8-22 - - //set gpio irq triger type - if(num < 4){//[0,3] - shift = num; - offset = 0x0300; - }else if(num >= 4 && num < 8){//[4,7] - shift = num-4; - offset = 0x0304; - }else if (num >= 8 && num <12){// [8,11] - shift = num-8; - offset = 0x0308; - } - else if (num>=12 && num < 16) - { - shift = num -12; - offset = 0x030c; - } - else if (num>=16 && num <20) - { - shift = num -16; - offset = 0x0310; - } - else ////vdout11 12 18:21-->gpio 31 32 38:41 - { // 0x0314----0x0319 - switch (num) - { - case WMT_PIN_GP5_VDOUT11: - shift = 0; - offset = 0x0314; - break; - case WMT_PIN_GP5_VDOUT12: - shift = 1; - offset = 0x0314; - break; - - case WMT_PIN_GP6_VDOUT18: - shift = 2; - offset = 0x0314; - break; - - case WMT_PIN_GP6_VDOUT19: - shift = 3; - offset = 0x0314; - break; - case WMT_PIN_GP6_VDOUT20: - shift = 0; - offset = 0x0318; - break; - - case WMT_PIN_GP6_VDOUT21: - - shift = 1; - offset = 0x0318; - break; - } - #if 0 - else if (num>=20 && num<24) //videoOut11 12 18 19 - { - shift = num -20; - offset = 0x0314; - } - else if (num>=24 && num<28) //videoOut20 21 - { - shift = num -24; - offset = 0x0318; - } - #endif - } - - reg = REG32_VAL(__GPIO_BASE + offset); - - switch(type){ - case IRQ_TYPE_LEVEL_LOW: - reg &= ~(1<<(shift*8+2)); - reg &= ~(1<<(shift*8+1)); - reg &= ~(1<<(shift*8)); - break; - case IRQ_TYPE_LEVEL_HIGH: - reg &= ~(1<<(shift*8+2)); - reg &= ~(1<<(shift*8+1)); - reg |= (1<<(shift*8)); - break; - case IRQ_TYPE_EDGE_FALLING: - reg &= ~(1<<(shift*8+2)); - reg |= (1<<(shift*8+1)); - reg &= ~(1<<(shift*8)); - break; - case IRQ_TYPE_EDGE_RISING: - reg &= ~(1<<(shift*8+2)); - reg |= (1<<(shift*8+1)); - reg |= (1<<(shift*8)); - break; - default://both edge - reg |= (1<<(shift*8+2)); - reg &= ~(1<<(shift*8+1)); - reg &= ~(1<<(shift*8)); - break; - - } - //reg |= 1<<(shift*8+7);//enable interrupt - reg &= ~(1<<(shift*8+7)); //disable int - - REG32_VAL(__GPIO_BASE + offset) = reg; - wmt_clr_int(); //replace 2014-8-22 - //REG32_VAL(__GPIO_BASE+0x0360) = 1<<num; //clear interrupt status// 1 bit per int - msleep(5); - return 0; -} - -int wmt_enable_gpirq(void) -{ - int num = irq_gpio; - - if(num > /*11*/ /*19*/42) - return -1; - - if(num<4) - REG32_VAL(__GPIO_BASE+0x0300) |= 1<<(num*8+7); //enable interrupt - else if(num >= 4 && num < 8) - REG32_VAL(__GPIO_BASE+0x0304) |= 1<<((num-4)*8+7); //enable interrupt - else if (num >= 8 && num < 12) - REG32_VAL(__GPIO_BASE+0x0308) |= 1<<((num-8)*8+7); //enable interrupt - else if (num >= 12 && num < 16) - REG32_VAL(__GPIO_BASE+0x030c) |= 1<<((num-12)*8+7); //enable interrupt - else if (num >= 16 && num < 20) - REG32_VAL(__GPIO_BASE+0x0310) |= 1<<((num-16)*8+7); //enable interrupt - else ////vdout11 12 18:21-->gpio 31 32 38:41 - { // 0x0314----0x0319 - switch (num) - { - case WMT_PIN_GP5_VDOUT11: - REG32_VAL(__GPIO_BASE+0x0314) |= 1<<(0*8+7); //enable interrupt - - break; - case WMT_PIN_GP5_VDOUT12: - REG32_VAL(__GPIO_BASE+0x0314) |= 1<<(1*8+7); //enable interrupt - break; - - case WMT_PIN_GP6_VDOUT18: - REG32_VAL(__GPIO_BASE+0x0314) |= 1<<(2*8+7); //enable interrupt - break; - - case WMT_PIN_GP6_VDOUT19: - REG32_VAL(__GPIO_BASE+0x0314) |= 1<<(3*8+7); //enable interrupt - break; - case WMT_PIN_GP6_VDOUT20: - REG32_VAL(__GPIO_BASE+0x0318) |= 1<<(0*8+7); //enable interrupt - - break; - - case WMT_PIN_GP6_VDOUT21: - - REG32_VAL(__GPIO_BASE+0x0318) |= 1<<(1*8+7); //enable interrupt - break; - } - - } - - return 0; -} - -int wmt_disable_gpirq(void) -{ - int num = irq_gpio; - - if(num > /*11*//*19*/42) - return -1; - - if(num<4) - REG32_VAL(__GPIO_BASE+0x0300) &= ~(1<<(num*8+7)); //disable interrupt - else if(num >= 4 && num < 8) - REG32_VAL(__GPIO_BASE+0x0304) &= ~(1<<((num-4)*8+7)); //enable interrupt - else if (num >= 8 && num <12) - REG32_VAL(__GPIO_BASE+0x0308) &= ~(1<<((num-8)*8+7)); //enable interrupt - else if (num >= 12 && num <16) - REG32_VAL(__GPIO_BASE+0x030c) &= ~(1<<((num-8)*8+7)); //enable interrupt - else if (num >= 16 && num <20) - REG32_VAL(__GPIO_BASE+0x0310) &= ~(1<<((num-8)*8+7)); //enable interrupt - else ////vdout11 12 18:21-->gpio 31 32 38:41 - { // 0x0314----0x0319 - switch (num) - { - case WMT_PIN_GP5_VDOUT11: - REG32_VAL(__GPIO_BASE+0x0314) &= ~(1<<(0*8+7)); //enable interrupt - - break; - case WMT_PIN_GP5_VDOUT12: - REG32_VAL(__GPIO_BASE+0x0314) &= ~(1<<(1*8+7)); //enable interrupt - break; - - case WMT_PIN_GP6_VDOUT18: - REG32_VAL(__GPIO_BASE+0x0314) &= ~(1<<(2*8+7)); //enable interrupt - break; - - case WMT_PIN_GP6_VDOUT19: - REG32_VAL(__GPIO_BASE+0x0314) &= ~(1<<(3*8+7)); //enable interrupt - break; - case WMT_PIN_GP6_VDOUT20: - REG32_VAL(__GPIO_BASE+0x0318) &= ~(1<<(0*8+7)); //enable interrupt - - break; - - case WMT_PIN_GP6_VDOUT21: - - REG32_VAL(__GPIO_BASE+0x0318) &= ~(1<<(1*8+7)); //enable interrupt - break; - } - - } - - return 0; -} - -static int pn544_wmt_is_int(int num) -{ - if (num > 42) - { - return 0; - } - if (num < 20) - { - return REG32_VAL(__GPIO_BASE+0x0360) & (1<<num) ? 1 : 0; - } - else - { - switch (num) - { - case WMT_PIN_GP5_VDOUT11: - return REG32_VAL(__GPIO_BASE+0x0360) & (1<<20) ? 1 : 0; - break; - case WMT_PIN_GP5_VDOUT12: - return REG32_VAL(__GPIO_BASE+0x0360) & (1<<21) ? 1 : 0; - break; - case WMT_PIN_GP6_VDOUT18: - return REG32_VAL(__GPIO_BASE+0x0360) & (1<<22) ? 1 : 0; - break; - case WMT_PIN_GP6_VDOUT19: - return REG32_VAL(__GPIO_BASE+0x0360) & (1<<23) ? 1 : 0; - break; - case WMT_PIN_GP6_VDOUT20: - return REG32_VAL(__GPIO_BASE+0x0360) & (1<<24) ? 1 : 0; - break; - case WMT_PIN_GP6_VDOUT21: - return REG32_VAL(__GPIO_BASE+0x0360) & (1<<25) ? 1 : 0; - break; - - } - - } - //return (REG32_VAL(__GPIO_BASE+0x0360) & (1<<num)) ? 1: 0; -} -//*************add end - - -static void pn544_disable_irq(struct pn544_dev *pn544_dev) -{ - unsigned long flags; - - spin_lock_irqsave(&pn544_dev->irq_enabled_lock, flags); - if (pn544_dev->irq_enabled) { - wmt_disable_gpirq(); - //disable_irq_nosync(pn544_dev->client->irq); - pn544_dev->irq_enabled = false; - } - spin_unlock_irqrestore(&pn544_dev->irq_enabled_lock, flags); -} - -static irqreturn_t pn544_dev_irq_handler(int irq, void *dev_id) -{ - struct pn544_dev *pn544_dev = dev_id; - //printk("<<<<<<<%s!\n", __func__); -#if 0 - if (!gpio_get_value(pn544_dev->irq_gpio)) { - - return IRQ_NONE; - //return IRQ_HANDLED;//??? - } -#endif - if (pn544_wmt_is_int(pn544_dev->irq_gpio)) - { - wmt_clr_int(); - pn544_disable_irq(pn544_dev); - - //printk("<<<<<<<%s! wakeup reader!\n", __func__); - /* Wake up waiting readers */ - wake_up(&pn544_dev->read_wq); - return IRQ_HANDLED; - } - else - { - return IRQ_NONE; - } -} - -static ssize_t pn544_dev_read(struct file *filp, char __user *buf, - size_t count, loff_t *offset) -{ - struct pn544_dev *pn544_dev = filp->private_data; - char tmp[MAX_BUFFER_SIZE]; - int ret,i; - - if (count > MAX_BUFFER_SIZE) - count = MAX_BUFFER_SIZE; - - printk("%s : reading %zu bytes.\n", __func__, count); - - mutex_lock(&pn544_dev->read_mutex); - - printk("%s irq gpio %d val %d\n", __func__, pn544_dev->irq_gpio, gpio_get_value(pn544_dev->irq_gpio)); - if (/*!gpio_get_value(pn544_dev->irq_gpio)*/gpio_get_value(pn544_dev->irq_gpio)!=pn544_dev->irq_active) { - printk("%s &&& waitting for interrupt!\n", __func__); - if (filp->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - goto fail; - } - - while (1) { - pn544_dev->irq_enabled = true; - wmt_enable_gpirq(); - //enable_irq(pn544_dev->client->irq); - - printk("%s &&& enter waitting for interrupt!\n", __func__); - - ret = wait_event_interruptible( - pn544_dev->read_wq, - !pn544_dev->irq_enabled/*false??*/); - - /*ret = wait_event_interruptible(pn544_dev->read_wq, - gpio_get_value(pn544_dev->irq_gpio)); - */ - - pn544_disable_irq(pn544_dev); - - if (ret) - goto fail; - if (gpio_get_value(pn544_dev->irq_gpio)==pn544_dev->irq_active) - break; - - pr_warning("%s: spurious interrupt detected\n", __func__); - } - } - - /* Read data */ - ret = i2c_master_recv(pn544_dev->client, tmp, count); - mutex_unlock(&pn544_dev->read_mutex); - /* pn544 seems to be slow in handling I2C read requests - * so add 1ms delay after recv operation */ - udelay(1000); - - if (ret < 0) { - pr_err("%s: i2c_master_recv returned %d\n", __func__, ret); - return ret; - } - if (ret > count) { - pr_err("%s: received too many bytes from i2c (%d)\n", - __func__, ret); - return -EIO; - } - if (copy_to_user(buf, tmp, ret)) { - pr_warning("%s : failed to copy to user space\n", __func__); - return -EFAULT; - } - - printk("IFD->PC:"); - for(i = 0; i < ret; i++){ - printk(" %02X", tmp[i]); - } - printk("\n"); - - return ret; - -fail: - printk("%s fail end! ret :%x\n", __func__, ret); - mutex_unlock(&pn544_dev->read_mutex); - return ret; -} - -static ssize_t pn544_dev_write(struct file *filp, const char __user *buf, - size_t count, loff_t *offset) -{ - struct pn544_dev *pn544_dev; - char tmp[MAX_BUFFER_SIZE]; - int ret,i; - - pn544_dev = filp->private_data; - - if (count > MAX_BUFFER_SIZE) - count = MAX_BUFFER_SIZE; - - if (copy_from_user(tmp, buf, count)) { - pr_err("%s : failed to copy from user space\n", __func__); - return -EFAULT; - } - - printk("%s : writing %zu bytes.\n", __func__, count); - /* Write data */ - ret = i2c_master_send(pn544_dev->client, tmp, count); - if (ret != count) { - pr_err("%s : i2c_master_send returned %d\n", __func__, ret); - ret = -EIO; - } - printk("PC->IFD:"); - for(i = 0; i < count; i++){ - printk(" %02X", tmp[i]); - } - /* pn544 seems to be slow in handling I2C write requests - * so add 1ms delay after I2C send oparation */ - udelay(1000); - - return ret; -} - -static int pn544_dev_open(struct inode *inode, struct file *filp) -{ - struct pn544_dev *pn544_dev = container_of(filp->private_data, - struct pn544_dev, - pn544_device); - - filp->private_data = pn544_dev; - - pr_debug("%s : %d,%d\n", __func__, imajor(inode), iminor(inode)); - - return 0; -} - -static /*int*/long pn544_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct pn544_dev *pn544_dev = filp->private_data; - - switch (cmd) { - case PN544_SET_PWR: - if (arg == 2) { - /* power on with firmware download (requires hw reset) - */ - printk("%s power on with firmware\n", __func__); - gpio_set_value(pn544_dev->ven_gpio, /*1*/pn544_dev->ven_active); - msleep(20); - if (pn544_dev->firm_gpio >= 0) - gpio_set_value(pn544_dev->firm_gpio, /*1*/pn544_dev->firm_active); - msleep(20); - gpio_set_value(pn544_dev->ven_gpio, /*0*/!pn544_dev->ven_active); - msleep(100); - gpio_set_value(pn544_dev->ven_gpio, /*1*/pn544_dev->ven_active); - msleep(20); - pn544_dev->ven_on_off = 1; - } else if (arg == 1) { - /* power on */ - printk("%s power on\n", __func__); - if (pn544_dev->firm_gpio >= 0) - gpio_set_value(pn544_dev->firm_gpio, /*0*/!pn544_dev->firm_active); - gpio_set_value(pn544_dev->ven_gpio, /*1*/pn544_dev->ven_active); - msleep(100); - pn544_dev->ven_on_off = 1; - } else if (arg == 0) { - /* power off */ - printk("%s power off ven %d \n", __func__, !pn544_dev->ven_active); - if (pn544_dev->firm_gpio >= 0) - gpio_set_value(pn544_dev->firm_gpio, /*0*/!pn544_dev->firm_active); - gpio_set_value(pn544_dev->ven_gpio, /*0*/!pn544_dev->ven_active); - - pn544_dev->ven_on_off = 0; - //gpio_set_value(pn544_dev->ven_gpio, 0); - msleep(100); - } else { - printk("%s bad arg %u\n", __func__, arg); - return -EINVAL; - } - break; - default: - printk("%s bad ioctl %u\n", __func__, cmd); - return -EINVAL; - } - - return 0; -} - -static const struct file_operations pn544_dev_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = pn544_dev_read, - .write = pn544_dev_write, - .open = pn544_dev_open, - .unlocked_ioctl = pn544_dev_ioctl, -}; - - -static int pn544_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int ret; - struct pn544_nfc_platform_data *platform_data; - struct pn544_dev *pn544_dev; - - platform_data = client->dev.platform_data; - - if (platform_data == NULL) { - pr_err("%s : nfc probe fail\n", __func__); - return -ENODEV; - } - - printk("nfc probe step01 is ok\n"); - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - pr_err("%s : need I2C_FUNC_I2C\n", __func__); - return -ENODEV; - } - - printk("nfc probe step02 is ok\n"); - - ret = gpio_request(platform_data->irq_gpio, "nfc_int"); - if (ret) - return -ENODEV; - - - - ret = gpio_request(platform_data->ven_gpio, "nfc_ven"); - if (ret) - goto err_ven; - - - if (platform_data->firm_gpio >= 0) - { - - ret = gpio_request(platform_data->firm_gpio, "nfc_firm"); - if (ret) - goto err_firm; - - } - - pn544_dev = kzalloc(sizeof(*pn544_dev), GFP_KERNEL); - if (pn544_dev == NULL) { - dev_err(&client->dev, - "failed to allocate memory for module data\n"); - ret = -ENOMEM; - goto err_exit; - } - - printk("nfc probe step04 is ok\n"); - - //pn544_dev->irq_enable = platform_data->irq_enable; - pn544_dev->irq_gpio = platform_data->irq_gpio; - pn544_dev->irq_active = platform_data->irq_active; - - //pn544_dev->ven_enable = platform_data->ven_enable; - pn544_dev->ven_gpio = platform_data->ven_gpio; - pn544_dev->ven_active = platform_data->ven_active; - pn544_dev->ven_on_off = 0; - //pn544_dev->firm_enable = platform_data->firm_enable; - pn544_dev->firm_gpio = platform_data->firm_gpio; - pn544_dev->firm_active = platform_data->firm_active; - - pn544_dev->client = client; - - irq_gpio = pn544_dev->irq_gpio; - /* init mutex and queues */ - init_waitqueue_head(&pn544_dev->read_wq); - mutex_init(&pn544_dev->read_mutex); - spin_lock_init(&pn544_dev->irq_enabled_lock); - - pn544_dev->pn544_device.minor = MISC_DYNAMIC_MINOR; - switch (g_chip_nr) - { - case 7: - pn544_dev->pn544_device.name = "pn547"; //"pn544" modify 2014-7-21 - break; - case 4: - pn544_dev->pn544_device.name = "pn544"; //"pn544" modify 2014-8-22 - break; - } - pn544_dev->pn544_device.fops = &pn544_dev_fops; - - ret = misc_register(&pn544_dev->pn544_device); - if (ret) { - pr_err("%s : misc_register failed\n", __FILE__); - goto err_misc_register; - } - printk("nfc probe step05 is ok\n"); - - /* request irq. the irq is set whenever the chip has data available - * for reading. it is cleared when all data has been read. - */ - - - gpio_direction_output(platform_data->ven_gpio,/*0*/ !platform_data->ven_active); - - if (platform_data->firm_gpio >= 0) - gpio_direction_output(platform_data->firm_gpio,/*0*/!platform_data->firm_active); - //s3c_gpio_setpull(platform_data->ven_gpio, S3C_GPIO_PULL_UP); - //s3c_gpio_setpull(platform_data->firm_gpio, S3C_GPIO_PULL_DOWN); - - //eint16 setting - - gpio_direction_input(platform_data->irq_gpio); - //wmt_gpio_setpull(platform_data->irq_gpio, WMT_GPIO_PULL_UP); - if (platform_data->irq_active) - { - printk("%s irq pull down!\n", __func__); - wmt_gpio_setpull(platform_data->irq_gpio, WMT_GPIO_PULL_DOWN); //modify 2014-7-16 - } - else - { - printk("%s irq pull up!\n", __func__); - wmt_gpio_setpull(platform_data->irq_gpio, WMT_GPIO_PULL_UP); - } - //s3c_gpio_setpull(platform_data->irq_gpio, S3C_GPIO_PULL_UP); - - - pr_info("%s : requesting IRQ %d\n", __func__, client->irq); - pn544_dev->irq_enabled = true; - - ret = request_irq(client->irq, pn544_dev_irq_handler, - /*platform_data->irq_active?IRQF_TRIGGER_HIGH:IRQF_TRIGGER_LOW*/IRQF_SHARED, \ - client->name, pn544_dev);//IRQF_TRIGGER_RISING IRQF_TRIGGER_HIGH - if (ret) { - printk(/*&client->dev, */"request_irq failed\n"); - goto err_request_irq_failed; - } - printk("nfc probe step06 is ok\n"); - //add 2014-7-16 for gpio irq config - wmt_set_irqinput(); - wmt_set_gpirq(platform_data->irq_active?IRQF_TRIGGER_HIGH:IRQF_TRIGGER_LOW); //IRQF_TRIGGER_HIGH - //wmt_enable_gpirq(); - //add end - - pn544_disable_irq(pn544_dev); - i2c_set_clientdata(client, pn544_dev); - - //add debug 2014-7-10 -#if 0 - printk("%s power on\n", __func__); - gpio_set_value(pn544_dev->firm_gpio, 0); - gpio_set_value(pn544_dev->ven_gpio, 1); - msleep(10); - - int maddr = 1; - char mbuf[2] = {0}; - for (maddr=1; maddr<0x7f; maddr++) - { - mbuf[0] = maddr; - /* Write data */ - //pn544_dev->client->addr = maddr; - ret = i2c_master_send(pn544_dev->client, mbuf, 1); - if (ret != 1) { - pr_err("%s : reg 0x%x i2c_master_send returned %d\n", __func__, maddr, ret); - //ret = -EIO; - } - else - { - pr_err("%s ok!!!: reg 0x%x i2c_master_send returned %d\n", __func__, maddr, ret); - //break; - } - - struct i2c_msg msg[2] = { - {.addr = client->addr, - .flags = 0|I2C_M_NOSTART, - .len = 1, - .buf = &mbuf[0], - }, - { .addr = client->addr, - .flags = I2C_M_RD, - .len = 1, - .buf = &mbuf[1], - }, - }; - - ret = i2c_transfer(client->adapter, msg, 2); - - //ret = i2c_master_recv(pn544_dev->client, mbuf, 1); - if (ret != 2) { - pr_err("%s : addr 0x%x i2c_master_recv %d returned %d\n", __func__, maddr, mbuf[1], ret); - //ret = -EIO; - } - else - { - pr_err("%s ok!!!: addr 0x%x i2c_master_recv %d returned %d\n", __func__, maddr, mbuf[1], ret); - //break; - } - - } -#endif - //add end - - printk("nfc probe step07 is ok\n"); - - return 0; - -err_request_irq_failed: - misc_deregister(&pn544_dev->pn544_device); -err_misc_register: - mutex_destroy(&pn544_dev->read_mutex); - kfree(pn544_dev); -err_exit: - if (platform_data->firm_gpio >= 0) - gpio_free(platform_data->firm_gpio); -err_firm: - - gpio_free(platform_data->ven_gpio); -err_ven: - - gpio_free(platform_data->irq_gpio); - return ret; -} - -static int pn544_remove(struct i2c_client *client) -{ - struct pn544_dev *pn544_dev; - - pn544_dev = i2c_get_clientdata(client); - free_irq(client->irq, pn544_dev); - misc_deregister(&pn544_dev->pn544_device); - mutex_destroy(&pn544_dev->read_mutex); - gpio_free(pn544_dev->irq_gpio); - gpio_free(pn544_dev->ven_gpio); - gpio_free(pn544_dev->firm_gpio); - kfree(pn544_dev); - - return 0; -} - -static const struct i2c_device_id pn544_id[] = { - { "pn544", 0 }, - { } -}; - -static int pn544_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct pn544_dev *pn544_dev; - - pn544_dev = i2c_get_clientdata(client); - printk("\n%s on_off %d\n", __func__, pn544_dev->ven_on_off); - return 0; -} - -static int pn544_resume(struct i2c_client *client) -{ - struct pn544_dev *pn544_dev; - - pn544_dev = i2c_get_clientdata(client); - - printk("%s on_off %d\n", __func__, pn544_dev->ven_on_off); - - gpio_direction_input(pn544_dev->irq_gpio); - //wmt_gpio_setpull(platform_data->irq_gpio, WMT_GPIO_PULL_UP); - if (pn544_dev->irq_active) - wmt_gpio_setpull(pn544_dev->irq_gpio, WMT_GPIO_PULL_DOWN); //modify 2014-7-16 - else - wmt_gpio_setpull(pn544_dev->irq_gpio, WMT_GPIO_PULL_UP); - - //add 2014-7-16 for gpio irq config - wmt_set_irqinput(); - wmt_set_gpirq(pn544_dev->irq_active?IRQF_TRIGGER_HIGH:IRQF_TRIGGER_LOW); //IRQF_TRIGGER_HIGH - //wmt_enable_gpirq(); - //add end - - pn544_disable_irq(pn544_dev); - - printk("%s active %d, !active %d\n", __func__, pn544_dev->ven_active, !pn544_dev->ven_active); - if (pn544_dev->ven_on_off) - gpio_set_value(pn544_dev->ven_gpio, pn544_dev->ven_active); - else - gpio_set_value(pn544_dev->ven_gpio, !pn544_dev->ven_active); - - //gpio_set_value(pn544_dev->ven_gpio, 0); - - return 0; -} -static struct i2c_driver pn544_driver = { - .id_table = pn544_id, - .probe = pn544_probe, - .remove = pn544_remove, - .suspend = pn544_suspend, - .resume = pn544_resume, - .driver = { - .owner = THIS_MODULE, - .name = "pn544", - }, -}; - -/* - * module load/unload record keeping - */ - -static struct pn544_nfc_platform_data pn544_pdata = { - //.irq_enable = 1, - .irq_gpio = WMT_PIN_GP0_GPIO0, - .irq_active = 1, - //.ven_enable = 1, - .ven_gpio= WMT_PIN_GP18_UART0RTS, // WMT_PIN_GP18_UART0RTS WMT_PIN_GP0_GPIO1 - .ven_active = 1, - //.firm_enable = 1, - .firm_gpio=WMT_PIN_GP0_GPIO1, //WMT_PIN_GP0_GPIO2, - .firm_active = 1, -}; -static int g_i2c_adapter = 0; -static int g_i2c_addr = 0x28; -static int get_board_info(void) -{ - int ret; - char buf[100] = {0}; - int len = sizeof(buf); - - char *pbuf = "wmt.nfc.pn54x"; // wmt.nfc.pn547 - printk("%s\n", __func__); - //wmt.nfc.pn54x 4:43:0:39:1:1:1:132:1 2b-->43 wmt.nfc.pn54x 4:43:0:39:1:1:0:132:1 - ret = wmt_getsyspara(pbuf, buf, &len); - if (!ret) - { - printk("%s %s:%s\n", __func__, pbuf, buf);//irq ven firm - - ret = sscanf(buf, "%d:%d:%d:%d:%d:%d:%d:%d:%d", \ - &g_chip_nr, &g_i2c_addr, &g_i2c_adapter, \ - &pn544_pdata.irq_gpio, &pn544_pdata.irq_active, \ - &pn544_pdata.ven_gpio, &pn544_pdata.ven_active, \ - &pn544_pdata.firm_gpio, &pn544_pdata.firm_active); - - printk("chip nr %d,i2c addr %d adapter %d, irq gpio %d active %d, ven %d %d, firm %d %d\n", \ - g_chip_nr, g_i2c_addr, g_i2c_adapter, \ - pn544_pdata.irq_gpio, pn544_pdata.irq_active, \ - pn544_pdata.ven_gpio, pn544_pdata.ven_active, \ - pn544_pdata.firm_gpio, pn544_pdata.firm_active); - - return 0; - } - else - { - printk("%s not get %s, use default\n", __func__, pbuf); - return -1; - } - - return 0; -} - -static int __init pn544_dev_init(void) -{ - //pr_info("Loading pn544 driver\n"); - - int r; - struct i2c_adapter *adapter; - - - - struct i2c_board_info wmt_pn544_bi = { - .type = PN544_DRIVER_NAME, - .flags = 0x00, - .addr = CLIENT_ADDR, - .platform_data = &pn544_pdata, //custom 2014-7-25 - .archdata = NULL, - .irq = IRQ_GPIO, - }; - //wmt_pn544_bi.addr = g_i2c_addr; - - pr_debug(DRIVER_DESC ": %s\n", __func__); - r = get_board_info(); - if (r < 0) - { - printk("%s no env!!\n", __func__); - return r; - } - wmt_pn544_bi.addr = g_i2c_addr; - adapter = i2c_get_adapter(/*WMT_PN544_I2C_CHANNEL*/g_i2c_adapter); - if (adapter == NULL) { - printk("can not get i2c adapter, client address error"); - return -ENODEV; - } - - pn544_client = i2c_new_device(adapter, &wmt_pn544_bi); - if ( pn544_client == NULL) { - printk("allocate i2c client failed"); - return -ENOMEM; - } - - i2c_put_adapter(adapter); - - r = i2c_add_driver(&pn544_driver); - if (r) { - pr_err(PN544_DRIVER_NAME ": driver registration failed\n"); - return r; - } - - return 0; - //return i2c_add_driver(&pn544_driver); -} -module_init(pn544_dev_init); - -static void __exit pn544_dev_exit(void) -{ - pr_info("Unloading pn544 driver\n"); - i2c_del_driver(&pn544_driver); - - i2c_unregister_device(pn544_client); -} -module_exit(pn544_dev_exit); - -MODULE_AUTHOR("Sylvain Fonteneau"); -MODULE_DESCRIPTION("NFC PN544 driver"); -MODULE_LICENSE("GPL"); |