# CONFIG_IOEXTEND_TCA6424 is not set
CONFIG_EXPANDED_GPIO_NUM=96
CONFIG_EXPANDED_GPIO_IRQ_NUM=16
+# CONFIG_EXPAND_GPIO_SOFT_INTERRUPT is not set
CONFIG_SPI_FPGA_GPIO_NUM=96
CONFIG_SPI_FPGA_GPIO_IRQ_NUM=16
# CONFIG_W1 is not set
/*
* InfoPhone Matrix Keyboard Device
*/
-
#define KEYOUT0 TCA6424_P01
#define KEYOUT1 TCA6424_P02
#define KEYOUT2 TCA6424_P03
#define KEYIN2 TCA6424_P14
#define KEYIN3 TCA6424_P15
-
-#if 1
static const uint32_t rk2818matrix_keymap[] = {
-#if 0
- KEY(0, 0, KEY_1),
- KEY(0, 1, KEY_3),
- KEY(0, 2, KEY_5),
- KEY(0, 3, KEY_6),
- KEY(0, 4, KEY_7),
- KEY(1, 0, KEY_2),
- KEY(1, 1, KEY_4),
- KEY(1, 2, KEY_R),
- KEY(1, 3, KEY_Y),
- KEY(1, 4, KEY_8),
- KEY(2, 0, KEY_TAB),
- KEY(2, 1, KEY_Q),
- KEY(2, 2, KEY_E),
- KEY(2, 3, KEY_T),
- KEY(2, 4, KEY_G),
- KEY(3, 0, KEY_LEFTCTRL),
- KEY(3, 1, KEY_W),
- KEY(3, 2, KEY_S),
- KEY(3, 3, KEY_F),
- KEY(3, 4, KEY_V),
-#else
KEY(0, 0, KEY_1),
KEY(1, 0, KEY_2),
KEY(2, 0, KEY_3),
KEY(1, 4, KEY_S),
KEY(2, 4, KEY_F),
KEY(3, 4, KEY_V),
-#endif
};
-#else
-static const uint32_t rk2818matrix_keymap[] = {
- KEY(0, 0, KEY_1),
- KEY(0, 1, KEY_2),
- KEY(0, 2, KEY_3),
- KEY(0, 3, KEY_TAB),
- KEY(1, 0, KEY_4),
- KEY(1, 1, KEY_5),
- KEY(1, 2, KEY_6),
- KEY(1, 3, KEY_R),
- KEY(2, 0, KEY_7),
- KEY(2, 1, KEY_8),
- KEY(2, 2, KEY_9),
- KEY(2, 3, KEY_LEFTCTRL),
- KEY(3, 0, KEY_SWITCHVIDEOMODE),
- KEY(3, 1, KEY_0),
- KEY(3, 2, KEY_S),
- KEY(3, 3, KEY_F),
- KEY(4, 0, KEY_G),
- KEY(4, 1, KEY_W),
- KEY(4, 2, KEY_S),
- KEY(4, 3, KEY_F),
-};
-
-#endif
static struct matrix_keymap_data rk2818matrix_keymap_data = {
.keymap = rk2818matrix_keymap,
int "setting the amount of expanded gpio irqs"
help
for tca6424, set 24
-config SOFT_INTERRUPT
+config EXPAND_GPIO_SOFT_INTERRUPT
bool "soft interrupt for expand gpio use"
help
if you want expand gpio support interrupt,choose it
obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o
obj-$(CONFIG_GPIO_PCA9554) += pca9554.o
obj-$(CONFIG_IOEXTEND_TCA6424) += tca6424.o
-obj-$(CONFIG_SOFT_INTERRUPT) += soft_interrupt.o
+obj-$(CONFIG_EXPAND_GPIO_SOFT_INTERRUPT) += expand_gpio_soft_interrupt.o
--- /dev/null
+/*\r
+ * Copyright (C) 2010 ROCKCHIP, Inc.\r
+ *\r
+ * This software is licensed under the terms of the GNU General Public\r
+ * License version 2, as published by the Free Software Foundation, and\r
+ * may be copied, distributed, and modified under those terms.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ */\r
+ \r
+/*******************************************************************/\r
+/* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED.*/\r
+/*******************************************************************\r
+FILE : Soft_interrupt.c\r
+MODIFY : sxj\r
+DATE : 2010-9-2\r
+NOTES :\r
+********************************************************************/\r
+#include <asm/mach/time.h>\r
+#include <linux/clk.h>\r
+#include <linux/errno.h>\r
+#include <linux/interrupt.h>\r
+#include <asm/mach-types.h>\r
+#include <linux/irq.h>\r
+#include <linux/debugfs.h>\r
+#include <linux/seq_file.h>\r
+#include <linux/kernel.h>\r
+#include <linux/list.h>\r
+#include <linux/module.h>\r
+#include <linux/io.h>\r
+#include <mach/hardware.h>\r
+#include <mach/gpio.h>\r
+#include <mach/rk2818_iomap.h>\r
+#include <mach/iomux.h>\r
+#include <linux/device.h>\r
+#include <mach/gpio.h>\r
+#include <asm/gpio.h>\r
+#include <linux/i2c.h>\r
+#include <linux/workqueue.h>\r
+#include <mach/board.h>\r
+#include <linux/delay.h>\r
+#include <linux/i2c/tca6424.h>\r
+#include <linux/ktime.h>\r
+#include "../drivers/gpio/expand_gpio_soft_interrupt.h"\r
+\r
+#if 0\r
+#define DBG(x...) printk(KERN_INFO x)\r
+#else\r
+#define DBG(x...)\r
+#endif\r
+\r
+#if 0\r
+#define DBGERR(x...) printk(KERN_INFO x)\r
+#else\r
+#define DBGERR(x...)\r
+#endif\r
+\r
+#define EXTPAND_GPIO_GET_BIT(a,num) (((a)>>(num))&0x01)\r
+#define EXTPAND_GPIO_SET_BIT(a,num) ((a)|(0x01<<(num)))\r
+#define EXTPAND_GPIO_CLEAR_BIT(a,num) ((a)&(~(0x01<<(num))))\r
+#define MIN(x,y) (((x)<(y))?(x):(y)) \r
+\r
+\r
+static int expand_gpio_irq_en = -1;\r
+static int expand_gpio_irq_ctrflag = -1;\r
+static unsigned int expand_gpio_irq_num = 0;\r
+\r
+static struct workqueue_struct *irqworkqueue;\r
+static struct lock_class_key gpio_lock_class;
+\r
+struct expand_gpio_soft_int expand_irq_data;\r
+\r
+void expand_gpio_irq_ctr_dis(int irq,int ctrflag)\r
+{\r
+ expand_gpio_irq_ctrflag=0;\r
+ if(expand_gpio_irq_en)\r
+ { \r
+ expand_gpio_irq_en=0;\r
+ disable_irq_nosync(irq);\r
+ DBG("***********%s %d***********\n",__FUNCTION__,__LINE__);\r
+ }\r
+ if(ctrflag)\r
+ {\r
+ expand_gpio_irq_ctrflag=-1;\r
+ }\r
+}\r
+\r
+void expand_gpio_irq_ctr_en(int irq)\r
+{ \r
+ if(!expand_gpio_irq_en)\r
+ { \r
+ DBG("***********%s %d***********\n",__FUNCTION__,__LINE__);\r
+ expand_gpio_irq_en = -1;\r
+ enable_irq(irq);\r
+ }\r
+}\r
+\r
+static int expand_checkrange(int start,int num,int val)\r
+{\r
+ \r
+ if((val<(start+num))&&(val>=start))\r
+ {\r
+ return 0;\r
+ }\r
+ else \r
+ {\r
+ return -1;\r
+ }\r
+\r
+}\r
+\r
+static void expand_gpio_irq_enable(unsigned irq)\r
+{\r
+ struct irq_desc *desc = irq_to_desc(irq);\r
+ struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)desc->chip_data;\r
+ uint8_t gpioPortNum;\r
+ uint8_t gpioPortPinNum; \r
+ uint8_t expandpinnum;\r
+\r
+ if(!expand_checkrange(pchip->gpio_irq_start,pchip->irq_pin_num,irq))\r
+ {\r
+ expandpinnum = irq - pchip->gpio_irq_start;//irq_to_gpio(irq)\r
+ }\r
+ else \r
+ {\r
+ return;\r
+ }\r
+ gpioPortNum = expandpinnum/(pchip->expand_port_pinnum);\r
+ gpioPortPinNum= expandpinnum%(pchip->expand_port_pinnum);\r
+\r
+ if((gpioPortNum>=(pchip->expand_port_group))||(gpioPortPinNum>=(pchip->expand_port_pinnum)))\r
+ return;\r
+ //DBG("**%s**\n",__FUNCTION__);\r
+ pchip->interrupt_en[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->interrupt_en[gpioPortNum],gpioPortPinNum); \r
+}\r
+static void expand_gpio_irq_disable(unsigned irq)\r
+{\r
+ struct irq_desc *desc = irq_to_desc(irq);\r
+ struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)desc->chip_data;\r
+ uint8_t gpioPortNum;\r
+ uint8_t gpioPortPinNum; \r
+ uint8_t expandpinnum;\r
+\r
+ if(!expand_checkrange(pchip->gpio_irq_start,pchip->irq_pin_num,irq))\r
+ {\r
+ expandpinnum=irq - pchip->gpio_irq_start;//irq_to_gpio(irq)\r
+ }\r
+ else \r
+ {\r
+ return;\r
+ }\r
+ gpioPortNum = expandpinnum/(pchip->expand_port_pinnum);\r
+ gpioPortPinNum= expandpinnum%(pchip->expand_port_pinnum);\r
+\r
+ if((gpioPortNum>=(pchip->expand_port_group))||(gpioPortPinNum>=(pchip->expand_port_pinnum)))\r
+ return;\r
+ //DBG("**%s**\n",__FUNCTION__);\r
+ pchip->interrupt_en[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->interrupt_en[gpioPortNum],gpioPortPinNum);\r
+ \r
+}\r
+\r
+static void expand_gpio_irq_mask(unsigned irq)\r
+{\r
+ struct irq_desc *desc = irq_to_desc(irq);\r
+ struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)desc->chip_data;\r
+ uint8_t gpioPortNum;\r
+ uint8_t gpioPortPinNum; \r
+ uint8_t expandpinnum;\r
+\r
+ if(!expand_checkrange(pchip->gpio_irq_start,pchip->irq_pin_num,irq))\r
+ {\r
+ expandpinnum=irq-pchip->gpio_irq_start;//irq_to_gpio(irq)\r
+ }\r
+ else \r
+ {\r
+ return;\r
+ }\r
+ gpioPortNum = expandpinnum/(pchip->expand_port_pinnum);\r
+ gpioPortPinNum= expandpinnum%(pchip->expand_port_pinnum);\r
+ if((gpioPortNum>=(pchip->expand_port_group))||(gpioPortPinNum>=(pchip->expand_port_pinnum)))\r
+ return;\r
+ //DBG("**%s**\n",__FUNCTION__);\r
+ pchip->interrupt_mask[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->interrupt_mask[gpioPortNum],gpioPortPinNum); \r
+}\r
+\r
+static void expand_gpio_irq_unmask(unsigned irq)\r
+{\r
+ struct irq_desc *desc = irq_to_desc(irq);\r
+ struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)desc->chip_data;\r
+ uint8_t gpioPortNum;\r
+ uint8_t gpioPortPinNum; \r
+ uint8_t expandpinnum;\r
+\r
+ if(!expand_checkrange(pchip->gpio_irq_start,pchip->irq_pin_num,irq))\r
+ {\r
+ expandpinnum=irq-pchip->gpio_irq_start;//irq_to_gpio(irq)\r
+ }\r
+ else \r
+ {\r
+ return;\r
+ }\r
+ gpioPortNum = expandpinnum/(pchip->expand_port_pinnum);\r
+ gpioPortPinNum= expandpinnum%(pchip->expand_port_pinnum);\r
+ if((gpioPortNum>=(pchip->expand_port_group))||(gpioPortPinNum>=(pchip->expand_port_pinnum)))\r
+ return;\r
+ //DBG("**%s**\n",__FUNCTION__);\r
+ pchip->interrupt_mask[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->interrupt_mask[gpioPortNum],gpioPortPinNum);\r
+}\r
+\r
+static int expand_gpio_irq_type(unsigned int irq, unsigned int type)\r
+{\r
+ struct irq_desc *desc_irq=irq_to_desc(irq);\r
+ struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)desc_irq->chip_data;\r
+ uint8_t gpioPortNum;\r
+ uint8_t gpioPortPinNum; \r
+ uint8_t expandpinnum;\r
+ if(!expand_checkrange(pchip->gpio_irq_start,pchip->irq_pin_num,irq))\r
+ {\r
+ expandpinnum = irq - pchip->gpio_irq_start;//irq_to_gpio(irq)\r
+ }\r
+ else\r
+ {\r
+ return -1;\r
+ }\r
+\r
+ gpioPortNum = expandpinnum/(pchip->expand_port_pinnum);\r
+ gpioPortPinNum= expandpinnum%(pchip->expand_port_pinnum);\r
+ if((gpioPortNum>=(pchip->expand_port_group))||(gpioPortPinNum>=(pchip->expand_port_pinnum)))\r
+ return -1;\r
+ DBG("**%s %d PortNum=%d,PortPinNum=%d**\n",__FUNCTION__,__LINE__,gpioPortNum,gpioPortPinNum);\r
+ switch (type) {\r
+ case IRQ_TYPE_NONE:\r
+ pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
+ DBG("**%s IRQ_TYPE_NONE**\n",__FUNCTION__);\r
+ break;\r
+ case IRQ_TYPE_EDGE_RISING:\r
+ pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
+ pchip->inttype[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->inttype[gpioPortNum],gpioPortPinNum);\r
+ pchip->inttype1[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype1[gpioPortNum],gpioPortPinNum);\r
+ DBG("**%s IRQ_TYPE_EDGE_RISING,inttype=%x,inttype1=%x**\n",__FUNCTION__,pchip->inttype[gpioPortNum],pchip->inttype1[gpioPortNum]);\r
+ break;\r
+ case IRQ_TYPE_EDGE_FALLING:\r
+ pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
+ pchip->inttype[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype[gpioPortNum],gpioPortPinNum);\r
+ pchip->inttype1[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype1[gpioPortNum],gpioPortPinNum); \r
+ DBG("**%s IRQ_TYPE_EDGE_RISING,inttype=%x,inttype1=%x**\n",__FUNCTION__,pchip->inttype[gpioPortNum],pchip->inttype1[gpioPortNum]);\r
+ break;\r
+ case IRQ_TYPE_EDGE_BOTH:\r
+ pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
+ pchip->inttype1[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->inttype1[gpioPortNum],gpioPortPinNum);\r
+ DBG("**%s IRQ_TYPE_EDGE_RISING,inttype=%x,inttype1=%x**\n",__FUNCTION__,pchip->inttype[gpioPortNum],pchip->inttype1[gpioPortNum]);\r
+ break;\r
+ case IRQ_TYPE_LEVEL_HIGH:\r
+ pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
+ DBG("extern gpios does not support IRQ_TYPE_LEVEL_HIGH irq typ");\r
+ break;\r
+ case IRQ_TYPE_LEVEL_LOW:\r
+ pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
+ DBG("extern gpios does not support IRQ_TYPE_LEVEL_LOW irq typ");\r
+ break;\r
+ default:\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int expand_gpio_irq_set_wake(unsigned irq, unsigned state)\r
+{\r
+ //no irq wake\r
+ return 0;\r
+}\r
+static struct irq_chip expand_gpio_irqchip = {\r
+ .name = "expand_gpio_expand ",\r
+ .enable = expand_gpio_irq_enable,\r
+ .disable = expand_gpio_irq_disable,\r
+ .mask = expand_gpio_irq_mask,\r
+ .unmask = expand_gpio_irq_unmask,\r
+ .set_type = expand_gpio_irq_type, \r
+ .set_wake = expand_gpio_irq_set_wake,\r
+};\r
+\r
+static irqreturn_t expand_gpio_irq_handler(int irq, void * dev_id)\r
+{\r
+ struct irq_desc *gpio_irq_desc = irq_to_desc(irq);\r
+ struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)gpio_irq_desc->chip_data;\r
+ u8 oldintputreg[MAX_SUPPORT_PORT_GROUP]={0,0,0,0,0};\r
+ u8 tempintputreg[MAX_SUPPORT_PORT_GROUP]={0,0,0,0,0};\r
+ u8 tempallowint=0; \r
+ u8 levelchg=0; \r
+ u8 intbit[MAX_SUPPORT_PORT_GROUP]={0,0,0,0,0}; \r
+ u8 tempinttype=0;\r
+ u8 int_en_flag=0;\r
+ int i,j;\r
+\r
+ DBG("******************%s*******************\n",__FUNCTION__);\r
+ expand_gpio_irq_ctr_dis(pchip->irq_chain,0);\r
+ memcpy(&oldintputreg[0],&pchip->gvar->reg_input[0],pchip->expand_port_pinnum);\r
+ if(pchip->irq_data.read_allinputreg(pchip->irq_data.data,&tempintputreg[0]))\r
+ {\r
+ expand_gpio_irq_ctr_dis(pchip->irq_chain,-1);\r
+ DBG("**%s[%d] reading reg is error\n",__FUNCTION__,__LINE__); \r
+ queue_work(irqworkqueue,&pchip->irq_work);\r
+ return IRQ_HANDLED;\r
+ }\r
+ \r
+ memcpy(&pchip->gvar->reg_input[0],&tempintputreg[0],pchip->expand_port_pinnum);\r
+ //DBG("**has run at %s**,input[0] = %x,input[1] = %x,input[2] = %x\n",__FUNCTION__,pchip->gvar.reg_input[0],pchip->gvar.reg_input[1],pchip->gvar.reg_input[2]);\r
+\r
+ //Handle for different expand_port_group \r
+ for(i=0,int_en_flag=0;i<MIN(pchip->expand_port_group,MAX_SUPPORT_PORT_GROUP);i++)\r
+ {\r
+ int_en_flag|=pchip->interrupt_en[i];\r
+ }\r
+\r
+ if(!int_en_flag)\r
+ { \r
+ if(expand_gpio_irq_num<0xFFFFFFFF)\r
+ {\r
+ expand_gpio_irq_num++;\r
+ }\r
+ else\r
+ {\r
+ expand_gpio_irq_num=0;\r
+ }\r
+ DBGERR("there are no pin reg irq\n"); \r
+ expand_gpio_irq_ctr_en(pchip->irq_chain);\r
+ return IRQ_HANDLED;\r
+ }\r
+\r
+ for(i=0;i<pchip->expand_port_group;i++)\r
+ {\r
+ tempallowint=pchip->interrupt_en[i]&pchip->gvar->reg_direction[i]&(~pchip->interrupt_mask[i]);// Âú×ãÖжÏÌõ¼þ\r
+ levelchg=oldintputreg[i]^tempintputreg[i];// ÕÒ³öÇ°ºó״̬²»Ò»ÑùµÄpin\r
+ tempinttype=~(tempintputreg[i]^pchip->inttype[i]);// ÕÒ³ö´¥·¢×´Ì¬ºÍµ±Ç°pin״̬һÑùµÄpin£¬×¢ÒâÖ»Ö§³Ölow highÁ½ÖÖpin´¥·¢\r
+\r
+ tempinttype=(~pchip->inttype1[i])&tempinttype;// inttype1 ΪÕæµÄλ¶ÔÓ¦µÄtempinttypeλÇåÁ㣬ÒòΪ¸ÃλֻÊÜinttype1¿ØÖÆ\r
+ tempinttype|=pchip->inttype1[i];//µçƽֻҪÊDZ仯¾Í²úÉúÖжÏ\r
+ tempinttype&=pchip->inttype_set[i];//ÒѾÉèÖÃÁËtypeÀàÐÍ\r
+\r
+ intbit[i]=tempallowint&levelchg&tempinttype;\r
+ //DBG(" tempallowint=%x,levelchg=%x,tempinttype=%x,intbit=%d\n",tempallowint,levelchg,tempinttype,intbit[i]);\r
+ }\r
+ if(expand_gpio_irq_num<0xFFFFFFFF)\r
+ {\r
+ expand_gpio_irq_num++;\r
+ }\r
+ else\r
+ {\r
+ expand_gpio_irq_num=0;\r
+ }\r
+ for(i=0;i<pchip->expand_port_group;i++)\r
+ {\r
+ if(intbit[i])\r
+ {\r
+ for(j=0;j<pchip->expand_port_pinnum;j++)\r
+ {\r
+ if(EXTPAND_GPIO_GET_BIT(intbit[i],j))\r
+ {\r
+ irq=pchip->gpio_irq_start+pchip->expand_port_pinnum*i+j;\r
+ gpio_irq_desc = irq_to_desc(irq);\r
+ gpio_irq_desc->chip->mask(irq);\r
+ generic_handle_irq(irq);\r
+ gpio_irq_desc->chip->unmask(irq);\r
+ //DBG("expand_i2c_irq_handler port=%d,pin=%d,pinlevel=%d\n",i,j,EXTPAND_GPIO_GET_BIT(tempintputreg[i],j));\r
+ }\r
+ }\r
+ }\r
+ }\r
+ expand_gpio_irq_ctr_en(pchip->irq_chain);\r
+ return IRQ_HANDLED;\r
+}\r
+\r
+static void irq_call_back_handler(struct work_struct *work)\r
+{\r
+ struct expand_gpio_soft_int *pchip = container_of(work, struct expand_gpio_soft_int,irq_work);\r
+ //printk("irq_call_back_handle\n");\r
+ expand_gpio_irq_handler(pchip->irq_chain,NULL);\r
+}\r
+\r
+void expand_gpio_irq_setup(struct expand_gpio_soft_int *pchip)\r
+{\r
+ unsigned int pioc, irq_num;\r
+ int ret;\r
+ struct irq_desc *desc;\r
+ irq_num = pchip->gpio_irq_start; //ÖжϺţ¬À©Õ¹ioµÄÖжϺÅÓ¦¸Ã½ô¸úÔÚÄÚ²¿ioÖжϺŵĺóÃæ¡£ÈçrkÄÚ²¿ÖжÏ48¸ö£¬¼ÓÉÏÄÚ²¿gpio 16¸öÐéÄâÖжϣ¬ÕâÀïpinÓ¦¸Ã´Ó48+16¿ªÊ¼\r
+\r
+ DBG("**%s**\n",__FUNCTION__);\r
+ for (pioc = 0; pioc < pchip->irq_pin_num; pioc++,irq_num++)\r
+ {\r
+ lockdep_set_class(&irq_desc[irq_num].lock, &gpio_lock_class);\r
+ /*\r
+ * Can use the "simple" and not "edge" handler since it's\r
+ * shorter, and the AIC handles interrupts sanely.\r
+ */\r
+ set_irq_chip(irq_num, &expand_gpio_irqchip); \r
+ set_irq_handler(irq_num, handle_simple_irq);\r
+ set_irq_chip_data(irq_num,(void *)pchip);\r
+ desc = irq_to_desc(irq_num);\r
+ DBG("**%s line=%d,irq_num=%d**\n",__FUNCTION__,__LINE__,irq_num);\r
+ set_irq_flags(irq_num, IRQF_VALID); \r
+ }\r
+ ret = gpio_request(pchip->irq_gpiopin,NULL);\r
+ if(ret!=0)\r
+ {\r
+ gpio_free(pchip->irq_gpiopin);\r
+ DBG("expand_gpio_irq_setup request gpio is err\n");\r
+ }\r
+ gpio_pull_updown(pchip->irq_gpiopin, pchip->rk_irq_gpio_pull_up_down); //gpio ÐèÒªÀ¸ßirq_to_gpio(pchip->irq_chain)\r
+ irqworkqueue=create_rt_workqueue("irq workqueue");\r
+ INIT_WORK(&pchip->irq_work,irq_call_back_handler);\r
+ set_irq_chip_data(pchip->irq_chain, pchip);\r
+ if(request_irq(pchip->irq_chain,expand_gpio_irq_handler,pchip->rk_irq_mode, "expand", pchip)!=0)\r
+ {\r
+ DBG("**%s line=%d is err**\n",__FUNCTION__,__LINE__);\r
+ }\r
+}\r
+\r
+int wait_untill_input_reg_flash(void)\r
+{\r
+ unsigned int num = 0;\r
+ unsigned int tempnum = expand_gpio_irq_num;\r
+\r
+ while(expand_gpio_irq_ctrflag&&(expand_gpio_irq_num==tempnum))\r
+ {\r
+ mdelay(1);\r
+ num++;\r
+ if(num>5)\r
+ return -1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+void expand_irq_init(void *data,struct expand_gpio_global_variable *var,irq_read_inputreg handler)\r
+{\r
+ expand_irq_data.irq_data.data = data;\r
+ expand_irq_data.irq_data.read_allinputreg = handler;\r
+ expand_irq_data.gvar = var;\r
+ expand_gpio_irq_setup(&expand_irq_data);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+#ifndef _SOFT_INTERRUPT_H\r
+#define _SOFT_INTERRUPT_H
+\r
+#define MAX_SUPPORT_PORT_GROUP 5\r
+\r
+typedef int (*irq_read_inputreg)(void *,char *);\r
+struct expand_gpio_irq_data\r
+{\r
+ void *data;\r
+ irq_read_inputreg read_allinputreg;\r
+};\r
+\r
+struct expand_gpio_global_variable\r
+{\r
+ uint8_t reg_input[MAX_SUPPORT_PORT_GROUP];\r
+ uint8_t reg_output[MAX_SUPPORT_PORT_GROUP];\r
+ uint8_t reg_direction[MAX_SUPPORT_PORT_GROUP];\r
+};\r
+struct expand_gpio_soft_int\r
+{\r
+ unsigned int gpio_irq_start;\r
+ unsigned int irq_pin_num; //ÖжϵĸöÊý\r
+ unsigned int irq_gpiopin; //¸¸ÖжϵÄÖÐ¶Ï ½Å\r
+ unsigned int irq_chain; //¸¸ÖжϵÄÖжϺÅ\r
+\r
+ unsigned int expand_port_group;\r
+ unsigned int expand_port_pinnum;\r
+ unsigned int rk_irq_mode;\r
+ unsigned int rk_irq_gpio_pull_up_down;\r
+ \r
+ uint8_t interrupt_en[MAX_SUPPORT_PORT_GROUP]; // 0 dis\r
+ uint8_t interrupt_mask[MAX_SUPPORT_PORT_GROUP]; // 0 unmask\r
+ uint8_t inttype_set[MAX_SUPPORT_PORT_GROUP]; // Inttype enable\r
+ uint8_t inttype[MAX_SUPPORT_PORT_GROUP]; \r
+ uint8_t inttype1[MAX_SUPPORT_PORT_GROUP];\r
+ \r
+ struct expand_gpio_irq_data irq_data;\r
+ struct work_struct irq_work;\r
+ struct expand_gpio_global_variable *gvar;\r
+};\r
+\r
+extern struct expand_gpio_soft_int expand_irq_data;\r
+extern int wait_untill_input_reg_flash(void);\r
+extern void expand_irq_init(void *data,struct expand_gpio_global_variable *var,irq_read_inputreg handler);\r
+\r
+#endif\r
+\r
+++ /dev/null
-/*\r
- * Copyright (C) 2010 ROCKCHIP, Inc.\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- */\r
- \r
-/*******************************************************************/\r
-/* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED.*/\r
-/*******************************************************************\r
-FILE : Soft_interrupt.c\r
-MODIFY : sxj\r
-DATE : 2010-9-2\r
-NOTES :\r
-********************************************************************/\r
-#include <asm/mach/time.h>\r
-#include <linux/clk.h>\r
-#include <linux/errno.h>\r
-#include <linux/interrupt.h>\r
-#include <asm/mach-types.h>\r
-#include <linux/irq.h>\r
-#include <linux/debugfs.h>\r
-#include <linux/seq_file.h>\r
-#include <linux/kernel.h>\r
-#include <linux/list.h>\r
-#include <linux/module.h>\r
-#include <linux/io.h>\r
-#include <mach/hardware.h>\r
-#include <mach/gpio.h>\r
-#include <mach/rk2818_iomap.h>\r
-#include <mach/iomux.h>\r
-#include <linux/device.h>\r
-#include <mach/gpio.h>\r
-#include <asm/gpio.h>\r
-#include <linux/i2c.h>\r
-#include <linux/workqueue.h>\r
-#include <mach/board.h>\r
-#include <linux/delay.h>\r
-#include <linux/i2c/tca6424.h>\r
-#include <linux/ktime.h>\r
-#include "../drivers/gpio/soft_interrupt.h"\r
-\r
-#if 0\r
-#define DBG(x...) printk(KERN_INFO x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
-\r
-#if 0\r
-#define DBGERR(x...) printk(KERN_INFO x)\r
-#else\r
-#define DBGERR(x...)\r
-#endif\r
-\r
-#define EXTPAND_GPIO_GET_BIT(a,num) (((a)>>(num))&0x01)\r
-#define EXTPAND_GPIO_SET_BIT(a,num) ((a)|(0x01<<(num)))\r
-#define EXTPAND_GPIO_CLEAR_BIT(a,num) ((a)&(~(0x01<<(num))))\r
-#define MIN(x,y) (((x)<(y))?(x):(y)) \r
-\r
-\r
-int expand_gpio_irq_en = -1;\r
-int expand_gpio_irq_ctrflag = -1;\r
-unsigned int expand_gpio_irq_num = 0;\r
-\r
-struct workqueue_struct *irqworkqueue;\r
-extern struct lock_class_key gpio_lock_class;\r
-struct expand_gpio_soft_int expand_irq_data;\r
-\r
-void expand_gpio_irq_ctr_dis(int irq,int ctrflag)\r
-{\r
- expand_gpio_irq_ctrflag=0;\r
- if(expand_gpio_irq_en)\r
- { \r
- expand_gpio_irq_en=0;\r
- disable_irq_nosync(irq);\r
- DBG("***********%s %d***********\n",__FUNCTION__,__LINE__);\r
- }\r
- if(ctrflag)\r
- {\r
- expand_gpio_irq_ctrflag=-1;\r
- }\r
-}\r
-\r
-void expand_gpio_irq_ctr_en(int irq)\r
-{ \r
- if(!expand_gpio_irq_en)\r
- { \r
- DBG("***********%s %d***********\n",__FUNCTION__,__LINE__);\r
- expand_gpio_irq_en = -1;\r
- enable_irq(irq);\r
- }\r
-}\r
-\r
-static int expand_checkrange(int start,int num,int val)\r
-{\r
- \r
- if((val<(start+num))&&(val>=start))\r
- {\r
- return 0;\r
- }\r
- else \r
- {\r
- return -1;\r
- }\r
-\r
-}\r
-\r
-static void expand_gpio_irq_enable(unsigned irq)\r
-{\r
- struct irq_desc *desc = irq_to_desc(irq);\r
- struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)desc->chip_data;\r
- uint8_t gpioPortNum;\r
- uint8_t gpioPortPinNum; \r
- uint8_t expandpinnum;\r
-\r
- if(!expand_checkrange(pchip->gpio_irq_start,pchip->irq_pin_num,irq))\r
- {\r
- expandpinnum = irq - pchip->gpio_irq_start;//irq_to_gpio(irq)\r
- }\r
- else \r
- {\r
- return;\r
- }\r
- gpioPortNum = expandpinnum/(pchip->expand_port_pinnum);\r
- gpioPortPinNum= expandpinnum%(pchip->expand_port_pinnum);\r
-\r
- if((gpioPortNum>=(pchip->expand_port_group))||(gpioPortPinNum>=(pchip->expand_port_pinnum)))\r
- return;\r
- //DBG("**%s**\n",__FUNCTION__);\r
- pchip->interrupt_en[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->interrupt_en[gpioPortNum],gpioPortPinNum); \r
-}\r
-static void expand_gpio_irq_disable(unsigned irq)\r
-{\r
- struct irq_desc *desc = irq_to_desc(irq);\r
- struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)desc->chip_data;\r
- uint8_t gpioPortNum;\r
- uint8_t gpioPortPinNum; \r
- uint8_t expandpinnum;\r
-\r
- if(!expand_checkrange(pchip->gpio_irq_start,pchip->irq_pin_num,irq))\r
- {\r
- expandpinnum=irq - pchip->gpio_irq_start;//irq_to_gpio(irq)\r
- }\r
- else \r
- {\r
- return;\r
- }\r
- gpioPortNum = expandpinnum/(pchip->expand_port_pinnum);\r
- gpioPortPinNum= expandpinnum%(pchip->expand_port_pinnum);\r
-\r
- if((gpioPortNum>=(pchip->expand_port_group))||(gpioPortPinNum>=(pchip->expand_port_pinnum)))\r
- return;\r
- //DBG("**%s**\n",__FUNCTION__);\r
- pchip->interrupt_en[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->interrupt_en[gpioPortNum],gpioPortPinNum);\r
- \r
-}\r
-\r
-static void expand_gpio_irq_mask(unsigned irq)\r
-{\r
- struct irq_desc *desc = irq_to_desc(irq);\r
- struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)desc->chip_data;\r
- uint8_t gpioPortNum;\r
- uint8_t gpioPortPinNum; \r
- uint8_t expandpinnum;\r
-\r
- if(!expand_checkrange(pchip->gpio_irq_start,pchip->irq_pin_num,irq))\r
- {\r
- expandpinnum=irq-pchip->gpio_irq_start;//irq_to_gpio(irq)\r
- }\r
- else \r
- {\r
- return;\r
- }\r
- gpioPortNum = expandpinnum/(pchip->expand_port_pinnum);\r
- gpioPortPinNum= expandpinnum%(pchip->expand_port_pinnum);\r
- if((gpioPortNum>=(pchip->expand_port_group))||(gpioPortPinNum>=(pchip->expand_port_pinnum)))\r
- return;\r
- //DBG("**%s**\n",__FUNCTION__);\r
- pchip->interrupt_mask[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->interrupt_mask[gpioPortNum],gpioPortPinNum); \r
-}\r
-\r
-static void expand_gpio_irq_unmask(unsigned irq)\r
-{\r
- struct irq_desc *desc = irq_to_desc(irq);\r
- struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)desc->chip_data;\r
- uint8_t gpioPortNum;\r
- uint8_t gpioPortPinNum; \r
- uint8_t expandpinnum;\r
-\r
- if(!expand_checkrange(pchip->gpio_irq_start,pchip->irq_pin_num,irq))\r
- {\r
- expandpinnum=irq-pchip->gpio_irq_start;//irq_to_gpio(irq)\r
- }\r
- else \r
- {\r
- return;\r
- }\r
- gpioPortNum = expandpinnum/(pchip->expand_port_pinnum);\r
- gpioPortPinNum= expandpinnum%(pchip->expand_port_pinnum);\r
- if((gpioPortNum>=(pchip->expand_port_group))||(gpioPortPinNum>=(pchip->expand_port_pinnum)))\r
- return;\r
- //DBG("**%s**\n",__FUNCTION__);\r
- pchip->interrupt_mask[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->interrupt_mask[gpioPortNum],gpioPortPinNum);\r
-}\r
-\r
-static int expand_gpio_irq_type(unsigned int irq, unsigned int type)\r
-{\r
- struct irq_desc *desc_irq=irq_to_desc(irq);\r
- struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)desc_irq->chip_data;\r
- uint8_t gpioPortNum;\r
- uint8_t gpioPortPinNum; \r
- uint8_t expandpinnum;\r
- if(!expand_checkrange(pchip->gpio_irq_start,pchip->irq_pin_num,irq))\r
- {\r
- expandpinnum = irq - pchip->gpio_irq_start;//irq_to_gpio(irq)\r
- }\r
- else\r
- {\r
- return -1;\r
- }\r
-\r
- gpioPortNum = expandpinnum/(pchip->expand_port_pinnum);\r
- gpioPortPinNum= expandpinnum%(pchip->expand_port_pinnum);\r
- if((gpioPortNum>=(pchip->expand_port_group))||(gpioPortPinNum>=(pchip->expand_port_pinnum)))\r
- return -1;\r
- DBG("**%s %d PortNum=%d,PortPinNum=%d**\n",__FUNCTION__,__LINE__,gpioPortNum,gpioPortPinNum);\r
- switch (type) {\r
- case IRQ_TYPE_NONE:\r
- pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
- DBG("**%s IRQ_TYPE_NONE**\n",__FUNCTION__);\r
- break;\r
- case IRQ_TYPE_EDGE_RISING:\r
- pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
- pchip->inttype[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->inttype[gpioPortNum],gpioPortPinNum);\r
- pchip->inttype1[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype1[gpioPortNum],gpioPortPinNum);\r
- DBG("**%s IRQ_TYPE_EDGE_RISING,inttype=%x,inttype1=%x**\n",__FUNCTION__,pchip->inttype[gpioPortNum],pchip->inttype1[gpioPortNum]);\r
- break;\r
- case IRQ_TYPE_EDGE_FALLING:\r
- pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
- pchip->inttype[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype[gpioPortNum],gpioPortPinNum);\r
- pchip->inttype1[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype1[gpioPortNum],gpioPortPinNum); \r
- DBG("**%s IRQ_TYPE_EDGE_RISING,inttype=%x,inttype1=%x**\n",__FUNCTION__,pchip->inttype[gpioPortNum],pchip->inttype1[gpioPortNum]);\r
- break;\r
- case IRQ_TYPE_EDGE_BOTH:\r
- pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
- pchip->inttype1[gpioPortNum]=EXTPAND_GPIO_SET_BIT(pchip->inttype1[gpioPortNum],gpioPortPinNum);\r
- DBG("**%s IRQ_TYPE_EDGE_RISING,inttype=%x,inttype1=%x**\n",__FUNCTION__,pchip->inttype[gpioPortNum],pchip->inttype1[gpioPortNum]);\r
- break;\r
- case IRQ_TYPE_LEVEL_HIGH:\r
- pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
- DBG("extern gpios does not support IRQ_TYPE_LEVEL_HIGH irq typ");\r
- break;\r
- case IRQ_TYPE_LEVEL_LOW:\r
- pchip->inttype_set[gpioPortNum]=EXTPAND_GPIO_CLEAR_BIT(pchip->inttype_set[gpioPortNum],gpioPortPinNum);\r
- DBG("extern gpios does not support IRQ_TYPE_LEVEL_LOW irq typ");\r
- break;\r
- default:\r
- return -EINVAL;\r
- }\r
- return 0;\r
-}\r
-\r
-static int expand_gpio_irq_set_wake(unsigned irq, unsigned state)\r
-{\r
- //no irq wake\r
- return 0;\r
-}\r
-static struct irq_chip expand_gpio_irqchip = {\r
- .name = "expand_gpio_expand ",\r
- .enable = expand_gpio_irq_enable,\r
- .disable = expand_gpio_irq_disable,\r
- .mask = expand_gpio_irq_mask,\r
- .unmask = expand_gpio_irq_unmask,\r
- .set_type = expand_gpio_irq_type, \r
- .set_wake = expand_gpio_irq_set_wake,\r
-};\r
-\r
-static irqreturn_t expand_gpio_irq_handler(int irq, void * dev_id)\r
-{\r
- struct irq_desc *gpio_irq_desc = irq_to_desc(irq);\r
- struct expand_gpio_soft_int *pchip=(struct expand_gpio_soft_int *)gpio_irq_desc->chip_data;\r
- u8 oldintputreg[MAX_SUPPORT_PORT_GROUP]={0,0,0,0,0};\r
- u8 tempintputreg[MAX_SUPPORT_PORT_GROUP]={0,0,0,0,0};\r
- u8 tempallowint=0; \r
- u8 levelchg=0; \r
- u8 intbit[MAX_SUPPORT_PORT_GROUP]={0,0,0,0,0}; \r
- u8 tempinttype=0;\r
- u8 int_en_flag=0;\r
- int i,j;\r
-\r
- DBG("******************%s*******************\n",__FUNCTION__);\r
- expand_gpio_irq_ctr_dis(pchip->irq_chain,0);\r
- memcpy(&oldintputreg[0],&pchip->gvar->reg_input[0],pchip->expand_port_pinnum);\r
- if(pchip->irq_data.read_allinputreg(pchip->irq_data.data,&tempintputreg[0]))\r
- {\r
- expand_gpio_irq_ctr_dis(pchip->irq_chain,-1);\r
- DBG("**%s[%d] reading reg is error\n",__FUNCTION__,__LINE__); \r
- queue_work(irqworkqueue,&pchip->irq_work);\r
- return IRQ_HANDLED;\r
- }\r
- \r
- memcpy(&pchip->gvar->reg_input[0],&tempintputreg[0],pchip->expand_port_pinnum);\r
- //DBG("**has run at %s**,input[0] = %x,input[1] = %x,input[2] = %x\n",__FUNCTION__,pchip->gvar.reg_input[0],pchip->gvar.reg_input[1],pchip->gvar.reg_input[2]);\r
-\r
- //Handle for different expand_port_group \r
- for(i=0,int_en_flag=0;i<MIN(pchip->expand_port_group,MAX_SUPPORT_PORT_GROUP);i++)\r
- {\r
- int_en_flag|=pchip->interrupt_en[i];\r
- }\r
-\r
- if(!int_en_flag)\r
- { \r
- if(expand_gpio_irq_num<0xFFFFFFFF)\r
- {\r
- expand_gpio_irq_num++;\r
- }\r
- else\r
- {\r
- expand_gpio_irq_num=0;\r
- }\r
- DBGERR("there are no pin reg irq\n"); \r
- expand_gpio_irq_ctr_en(pchip->irq_chain);\r
- return IRQ_HANDLED;\r
- }\r
-\r
- for(i=0;i<pchip->expand_port_group;i++)\r
- {\r
- tempallowint=pchip->interrupt_en[i]&pchip->gvar->reg_direction[i]&(~pchip->interrupt_mask[i]);// Âú×ãÖжÏÌõ¼þ\r
- levelchg=oldintputreg[i]^tempintputreg[i];// ÕÒ³öÇ°ºó״̬²»Ò»ÑùµÄpin\r
- tempinttype=~(tempintputreg[i]^pchip->inttype[i]);// ÕÒ³ö´¥·¢×´Ì¬ºÍµ±Ç°pin״̬һÑùµÄpin£¬×¢ÒâÖ»Ö§³Ölow highÁ½ÖÖpin´¥·¢\r
-\r
- tempinttype=(~pchip->inttype1[i])&tempinttype;// inttype1 ΪÕæµÄλ¶ÔÓ¦µÄtempinttypeλÇåÁ㣬ÒòΪ¸ÃλֻÊÜinttype1¿ØÖÆ\r
- tempinttype|=pchip->inttype1[i];//µçƽֻҪÊDZ仯¾Í²úÉúÖжÏ\r
- tempinttype&=pchip->inttype_set[i];//ÒѾÉèÖÃÁËtypeÀàÐÍ\r
-\r
- intbit[i]=tempallowint&levelchg&tempinttype;\r
- //DBG(" tempallowint=%x,levelchg=%x,tempinttype=%x,intbit=%d\n",tempallowint,levelchg,tempinttype,intbit[i]);\r
- }\r
- if(expand_gpio_irq_num<0xFFFFFFFF)\r
- {\r
- expand_gpio_irq_num++;\r
- }\r
- else\r
- {\r
- expand_gpio_irq_num=0;\r
- }\r
- for(i=0;i<pchip->expand_port_group;i++)\r
- {\r
- if(intbit[i])\r
- {\r
- for(j=0;j<pchip->expand_port_pinnum;j++)\r
- {\r
- if(EXTPAND_GPIO_GET_BIT(intbit[i],j))\r
- {\r
- irq=pchip->gpio_irq_start+pchip->expand_port_pinnum*i+j;\r
- gpio_irq_desc = irq_to_desc(irq);\r
- gpio_irq_desc->chip->mask(irq);\r
- generic_handle_irq(irq);\r
- gpio_irq_desc->chip->unmask(irq);\r
- //DBG("expand_i2c_irq_handler port=%d,pin=%d,pinlevel=%d\n",i,j,EXTPAND_GPIO_GET_BIT(tempintputreg[i],j));\r
- }\r
- }\r
- }\r
- }\r
- expand_gpio_irq_ctr_en(pchip->irq_chain);\r
- return IRQ_HANDLED;\r
-}\r
-\r
-static void irq_call_back_handler(struct work_struct *work)\r
-{\r
- struct expand_gpio_soft_int *pchip = container_of(work, struct expand_gpio_soft_int,irq_work);\r
- //printk("irq_call_back_handle\n");\r
- expand_gpio_irq_handler(pchip->irq_chain,NULL);\r
-}\r
-\r
-void expand_gpio_irq_setup(struct expand_gpio_soft_int *pchip)\r
-{\r
- unsigned int pioc, irq_num;\r
- int ret;\r
- struct irq_desc *desc;\r
- irq_num = pchip->gpio_irq_start; //ÖжϺţ¬À©Õ¹ioµÄÖжϺÅÓ¦¸Ã½ô¸úÔÚÄÚ²¿ioÖжϺŵĺóÃæ¡£ÈçrkÄÚ²¿ÖжÏ48¸ö£¬¼ÓÉÏÄÚ²¿gpio 16¸öÐéÄâÖжϣ¬ÕâÀïpinÓ¦¸Ã´Ó48+16¿ªÊ¼\r
-\r
- DBG("**%s**\n",__FUNCTION__);\r
- for (pioc = 0; pioc < pchip->irq_pin_num; pioc++,irq_num++)\r
- {\r
- lockdep_set_class(&irq_desc[irq_num].lock, &gpio_lock_class);\r
- /*\r
- * Can use the "simple" and not "edge" handler since it's\r
- * shorter, and the AIC handles interrupts sanely.\r
- */\r
- set_irq_chip(irq_num, &expand_gpio_irqchip); \r
- set_irq_handler(irq_num, handle_simple_irq);\r
- set_irq_chip_data(irq_num,(void *)pchip);\r
- desc = irq_to_desc(irq_num);\r
- DBG("**%s line=%d,irq_num=%d**\n",__FUNCTION__,__LINE__,irq_num);\r
- set_irq_flags(irq_num, IRQF_VALID); \r
- }\r
- ret = gpio_request(pchip->irq_gpiopin,NULL);\r
- if(ret!=0)\r
- {\r
- gpio_free(pchip->irq_gpiopin);\r
- DBG("expand_gpio_irq_setup request gpio is err\n");\r
- }\r
- gpio_pull_updown(pchip->irq_gpiopin, pchip->rk_irq_gpio_pull_up_down); //gpio ÐèÒªÀ¸ßirq_to_gpio(pchip->irq_chain)\r
- irqworkqueue=create_rt_workqueue("irq workqueue");\r
- INIT_WORK(&pchip->irq_work,irq_call_back_handler);\r
- set_irq_chip_data(pchip->irq_chain, pchip);\r
- if(request_irq(pchip->irq_chain,expand_gpio_irq_handler,pchip->rk_irq_mode, "expand", pchip)!=0)\r
- {\r
- DBG("**%s line=%d is err**\n",__FUNCTION__,__LINE__);\r
- }\r
-}\r
-\r
-int wait_untill_input_reg_flash(void)\r
-{\r
- unsigned int num = 0;\r
- unsigned int tempnum = expand_gpio_irq_num;\r
-\r
- while(expand_gpio_irq_ctrflag&&(expand_gpio_irq_num==tempnum))\r
- {\r
- mdelay(1);\r
- num++;\r
- if(num>5)\r
- return -1;\r
- }\r
- return 0;\r
-}\r
-\r
-void expand_irq_init(void *data,struct expand_gpio_global_variable *var,irq_read_inputreg handler)\r
-{\r
- expand_irq_data.irq_data.data = data;\r
- expand_irq_data.irq_data.read_allinputreg = handler;\r
- expand_irq_data.gvar = var;\r
- expand_gpio_irq_setup(&expand_irq_data);\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
+++ /dev/null
-#ifndef _SOFT_INTERRUPT_H\r
-#define _SOFT_INTERRUPT_H
-\r
-#define MAX_SUPPORT_PORT_GROUP 5\r
-\r
-typedef int (*irq_read_inputreg)(void *,char *);\r
-struct expand_gpio_irq_data\r
-{\r
- void *data;\r
- irq_read_inputreg read_allinputreg;\r
-};\r
-\r
-struct expand_gpio_global_variable\r
-{\r
- uint8_t reg_input[MAX_SUPPORT_PORT_GROUP];\r
- uint8_t reg_output[MAX_SUPPORT_PORT_GROUP];\r
- uint8_t reg_direction[MAX_SUPPORT_PORT_GROUP];\r
-};\r
-struct expand_gpio_soft_int\r
-{\r
- unsigned int gpio_irq_start;\r
- unsigned int irq_pin_num; //ÖжϵĸöÊý\r
- unsigned int irq_gpiopin; //¸¸ÖжϵÄÖÐ¶Ï ½Å\r
- unsigned int irq_chain; //¸¸ÖжϵÄÖжϺÅ\r
-\r
- unsigned int expand_port_group;\r
- unsigned int expand_port_pinnum;\r
- unsigned int rk_irq_mode;\r
- unsigned int rk_irq_gpio_pull_up_down;\r
- \r
- uint8_t interrupt_en[MAX_SUPPORT_PORT_GROUP]; // 0 dis\r
- uint8_t interrupt_mask[MAX_SUPPORT_PORT_GROUP]; // 0 unmask\r
- uint8_t inttype_set[MAX_SUPPORT_PORT_GROUP]; // Inttype enable\r
- uint8_t inttype[MAX_SUPPORT_PORT_GROUP]; \r
- uint8_t inttype1[MAX_SUPPORT_PORT_GROUP];\r
- \r
- struct expand_gpio_irq_data irq_data;\r
- struct work_struct irq_work;\r
- struct expand_gpio_global_variable *gvar;\r
-};\r
-\r
-extern struct expand_gpio_soft_int expand_irq_data;\r
-extern int wait_untill_input_reg_flash(void);\r
-extern void expand_irq_init(void *data,struct expand_gpio_global_variable *var,irq_read_inputreg handler);\r
-\r
-#endif\r
-\r
#include <linux/delay.h>
#include <linux/i2c/tca6424.h>
#include <linux/ktime.h>
-#include "../drivers/gpio/soft_interrupt.h"
+#include "../drivers/gpio/expand_gpio_soft_interrupt.h"
#if 0
#define TCA6424DEB
chip = container_of(gc, struct tca6424_chip, gpio_chip);
- #ifdef CONFIG_SOFT_INTERRUPT
+ #ifdef CONFIG_EXPAND_GPIO_SOFT_INTERRUPT
ret = wait_untill_input_reg_flash( );
if(ret<0)
return -1;
if((gpioPortNum>=TCA6424_PortNum)||(gpioPortPinNum>=portnum[gpioPortNum]))
return -1;
- #ifndef CONFIG_SOFT_INTERRUPT
+ #ifndef CONFIG_EXPAND_GPIO_SOFT_INTERRUPT
uint8_t reg_val;
ret = tca6424_read_reg(chip->client, Regaddr, ®_val);
if (ret < 0)
chip->client = client;
chip->names = pdata->names;
- #ifdef CONFIG_SOFT_INTERRUPT
+ #ifdef CONFIG_EXPAND_GPIO_SOFT_INTERRUPT
chip->expand = &expand_irq_data;
chip->expand->gpio_irq_start =pdata->gpio_irq_start;
chip->expand->irq_pin_num = pdata->irq_pin_num;
}
i2c_set_clientdata(client, chip);
- #ifdef CONFIG_SOFT_INTERRUPT
+ #ifdef CONFIG_EXPAND_GPIO_SOFT_INTERRUPT
expand_irq_init(chip,&chip->gtca6424_struct,tca6424_irq_read_inputreg);
#endif
return 0;