blob: d4b7366fe9fedecaf0e8615a0d285f135d79fb74 [file] [log] [blame]
/*
* linux/arch/arm/mach-zx297520v2/gpio.c
*
* Copyright (C) 2013 ZTE-TSP
*
* 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.
*/
#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/io.h>
#include <mach/iomap.h>
#include <mach/gpio.h>
#include <mach/gpio_def.h>
#include <mach/pcu.h>
#include <mach/debug.h>
#include <mach/spinlock.h>
#define GPIO0_NUM 128
#define gpio_write_reg_lock(a, v) \
do { \
reg_spin_lock(); \
zx_write_reg(a, v); \
reg_spin_unlock(); \
} while (0)
#define gpio_write_bits_lock(a, o, w, v) \
do { \
reg_spin_lock(); \
zx_write_bits(a, o, w, v); \
reg_spin_unlock(); \
} while (0)
/*
* select gpio multiplex function
* gpio: gpio number
* func: PIN_FUNC_SEL_AON/PIN_FUNC_SEL_PD
* according with register defination
*/
int zx29_gpio_function_sel(unsigned int gpio, gpio_func_id func )
{
int i ;
unsigned int func_sel = (func>>12)&0x1;
unsigned int value = func&0x3ff;
if((gpio != (func>>24))||(gpio > ZX29_GPIO_MAX))
return -EINVAL;
for(i=0; i<ARRAY_SIZE(pin_info); i++)
{
if(pin_info[i].gpio == gpio)
break;
/* no support */
if(pin_info[i].gpio == ZX29_GPIO_NULL)
return -ENODATA;
}
/* top_func_sel */
if(pin_info[i].top_func_sel_reg.reg_addr)
gpio_write_bits_lock(pin_info[i].top_func_sel_reg.reg_addr,
pin_info[i].top_func_sel_reg.reg_bit_offset,
pin_info[i].top_func_sel_reg.reg_bit_size,
func_sel);
if(PIN_FUNC_SEL_AON == func_sel)
{
if(pin_info[i].aon_func_sel_reg.reg_addr)
gpio_write_bits_lock(pin_info[i].aon_func_sel_reg.reg_addr,
pin_info[i].aon_func_sel_reg.reg_bit_offset,
pin_info[i].aon_func_sel_reg.reg_bit_size,
value);
}
else
{
if(pin_info[i].pd_func_sel_reg.reg_addr)
gpio_write_bits_lock(pin_info[i].pd_func_sel_reg.reg_addr,
pin_info[i].pd_func_sel_reg.reg_bit_offset,
pin_info[i].pd_func_sel_reg.reg_bit_size,
value);
}
return 0;
}
static unsigned int get_gpio_by_name(const char *pin_name)
{
int i ;
for(i=0; i<ARRAY_SIZE(pin_info); i++)
{
if (!strcmp(pin_name, pin_info[i].pin_name))
{
return pin_info[i].gpio;
}
}
return ZX29_GPIO_NULL;
}
int zx29_func_sel_by_name(const char *pin_name, gpio_func_id func)
{
unsigned int gpio = get_gpio_by_name(pin_name);
if(gpio == ZX29_GPIO_NULL)
{
pr_err("zx29_func_sel_by_name(%s) failed. \n", pin_name);
return -ENODATA;
}
return zx29_gpio_function_sel(gpio, func);
}
int zx29_gpio_function_sel_get(unsigned int gpio)
{
int i=0;
unsigned int func_sel = 0;
unsigned int top_func = 0;
unsigned int value = 0;
unsigned int temp=0,mask=0;
if((gpio<0)||(gpio > ZX29_GPIO_MAX))
return -EINVAL;
for(i=0; i<ARRAY_SIZE(pin_info); i++)
{
if(pin_info[i].gpio == gpio)
break;
/* not support*/
if(pin_info[i].gpio == ZX29_GPIO_NULL)
return -ENODATA;
}
/*top_func*/
if(pin_info[i].top_func_sel_reg.reg_addr)
{
temp=zx_read_reg(pin_info[i].top_func_sel_reg.reg_addr);
top_func = temp>>(pin_info[i].top_func_sel_reg.reg_bit_offset);
top_func = top_func&0x01;
}
else
{
top_func = PIN_FUNC_SEL_AON;
}
/*aon_func*/
if(top_func == PIN_FUNC_SEL_AON)
{
if(pin_info[i].aon_func_sel_reg.reg_addr)
{
temp = zx_read_reg(pin_info[i].aon_func_sel_reg.reg_addr);
value = temp>>(pin_info[i].aon_func_sel_reg.reg_bit_offset);
mask =(1<<pin_info[i].aon_func_sel_reg.reg_bit_size)-1;
value = value&mask;
}
else
value = 0;
}
else/*pd_func*/
{
if(pin_info[i].pd_func_sel_reg.reg_addr)
{
temp = zx_read_reg(pin_info[i].pd_func_sel_reg.reg_addr);
value = temp>>(pin_info[i].pd_func_sel_reg.reg_bit_offset);
mask =(1<<pin_info[i].pd_func_sel_reg.reg_bit_size)-1;
value =value&mask;
}
else
value = 0;
}
func_sel = (gpio<<24)|(top_func<<12)|value;
return func_sel;
}
/*
* set gpio resistance of pull-up and pull-down status
*@ gpio: gpio pin number
*@ config: IO_CFG enum
*@
*@ This function is only for config pu/pd, if select driver capacity,
*@ use another interface.
*/
void zx29_gpio_pd_pu_set(unsigned int gpio, unsigned int config)
{
int i ;
if(gpio > ZX29_GPIO_MAX)
return;
for(i=0; i<ARRAY_SIZE(pin_info); i++)
{
if(pin_info[i].gpio == gpio)
break;
/* no support */
if(pin_info[i].gpio == ZX29_GPIO_NULL)
return;
}
if(pin_info[i].io_cfg_reg.reg_addr)
gpio_write_bits_lock(pin_info[i].io_cfg_reg.reg_addr,
pin_info[i].io_cfg_reg.reg_bit_offset,
pin_info[i].io_cfg_reg.reg_bit_size,
config);
}
EXPORT_SYMBOL(zx29_gpio_pd_pu_set);
/****************************************************************
** gpio function
**
***************************************************************/
/*
* set direction
*
* 0:input 1:out
*/
void zx29_gpio_set_direction(unsigned int gpio, unsigned int dir)
{
unsigned int temp=0;
void __iomem *regaddr = NULL;
if(gpio < GPIO0_NUM)
regaddr = GPIOPDD_REG0(gpio);
else
{
gpio -= GPIO0_NUM;
regaddr = GPIOPDD_REG1(gpio);
}
temp = zx_read_reg(regaddr);
if(dir == GPIO_IN)
temp &= ~(1 << (gpio % 16));
else
temp |= (1 << (gpio % 16));
gpio_write_reg_lock(regaddr, temp);
}
/*
* get direction
*
* 0:input 1:out
*/
unsigned int zx29_gpio_get_direction(unsigned int gpio)
{
unsigned int temp=0;
if(gpio <GPIO0_NUM)
temp = zx_read_reg(GPIOPDD_REG0(gpio));
else
{
gpio -= GPIO0_NUM;
temp = zx_read_reg(GPIOPDD_REG1(gpio));
}
temp = temp >> (gpio % 16);
temp &= 0x1;
return temp;
}
/*
* gpio out
*
* 0:low 1:high
*/
void zx29_gpio_output_data(unsigned int gpio, unsigned int value)
{
unsigned int temp=0;
if(value == GPIO_LOW)
{
if(gpio <GPIO0_NUM)
{
temp = zx_read_reg(SET0_SEND_REG0(gpio));
temp |= (1 << (gpio % 16));
gpio_write_reg_lock(SET0_SEND_REG0(gpio), temp);
}
else{
gpio -= GPIO0_NUM;
temp = zx_read_reg(SET0_SEND_REG1(gpio));
temp |= (1 << (gpio % 16));
gpio_write_reg_lock(SET0_SEND_REG1(gpio), temp);
}
}else if(value == GPIO_HIGH)
{
if(gpio <GPIO0_NUM)
{
temp = zx_read_reg(SET1_SEND_REG0(gpio));
temp |= (1 << (gpio % 16));
gpio_write_reg_lock(SET1_SEND_REG0(gpio), temp);
}
else{
gpio -= GPIO0_NUM;
temp = zx_read_reg(SET1_SEND_REG1(gpio));
temp |= (1 << (gpio % 16));
gpio_write_reg_lock(SET1_SEND_REG1(gpio), temp);
}
}
}
/*
* gpio input
*
* 0:low 1:high
*/
unsigned int zx29_gpio_input_data(unsigned int gpio)
{
unsigned int value=0;
if(gpio < GPIO0_NUM)
value = zx_read_reg(RECV_REG0(gpio));
else
{
gpio -= GPIO0_NUM;
value = zx_read_reg(RECV_REG1(gpio));
}
return (value >> (gpio % 16)) & 0x1;
}
/*
* set extern int source type
*
* gpio: gpio number
*
* type: IRQ_TYPE_LEVEL_HIGH
* IRQ_TYPE_LEVEL_LOW
* IRQ_TYPE_EDGE_RISING
* IRQ_TYPE_EDGE_FALLING
*/
void zx29_gpio_set_inttype(unsigned int gpio, unsigned int type)
{
unsigned int index = 0;
/*****************************
** gpio50~~57 ---- ext0~~7
** gpio70~~77 ---- ext8~~15
*****************************/
if ((gpio>=50) && (gpio<=57))
index = gpio - 50 + (unsigned int)PCU_EX0_INT;
else if ((gpio>=70) && (gpio<=77))
index = gpio - 70 + (unsigned int)PCU_EX8_INT;
else
return;
pcu_int_set_type((PCU_INT_INDEX)index,type);
}
EXPORT_SYMBOL(zx29_gpio_set_inttype);
int zx29_gpio2irq(unsigned int gpio)
{
if ((gpio>=50) && (gpio<=57))
return(gpio - 50 + EX0_INT);
else if ((gpio>=70) && (gpio<=77))
return (gpio - 70 + EX8_INT);
return -EINVAL;
}
/*********************************************************************************************
*** jtag0: sd1_cmd/sd1_data0/sd1_data1/sd1_data2/sd1_data3
*** pd_func: 0: sd1 1:ps_jtag 2:phy_jtag 3:ap_jtag aon_func: 0:gpio 1:m0_jtag
***
*** jtag1: jtag_tck/jtag_tdi/jtag_tdo/jtag_tms/jtag_trst
*** pd_func: 0: ps_jtag 1:phy_jtag 2:ap_jtag aon_func: 0:m0_jtag 1:gpio
***
*** jtag2: kbc_0/kbc_2/kbr_0/kbr_1/kbr_2
*** pd_func: 0: ps_jtag 1:phy_jtag 2:ap_jtag aon_func: 0:key 1:gpio 2:ext_int 3:m0_jtag
***********************************************************************************************
*/
void jtag_config(unsigned int jtag_num, unsigned int function)
{
//unsigned int tmp = 0;
return ;
}
unsigned int zx29_gpio_outputdata_get(unsigned int gpio)
{
unsigned int temp=0;
if(gpio <GPIO0_NUM)
temp = zx_read_reg(SEND_REG0(gpio));
else
{
gpio -=GPIO0_NUM;
temp = zx_read_reg(SEND_REG1(gpio));
}
return (temp>>(gpio%16))&0x01;
}
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <asm/string.h>
static char temp_buf[50],temp[30];
unsigned char buf = 0;
static struct gpio_status{
char *function;
char *direction;
char *level;
}gpio_status_get;
struct zx29_gpio_def
{
char * gpio_name;
unsigned int gpio_num;
unsigned int gpio_func;
};
static struct zx29_gpio_def gpio_def[] =
{
{"GPIO0_GPIO0", 0, GPIO0_GPIO0},
{"GPIO0_NAND_WE", 0, GPIO0_NAND_WE},
{"GPIO1_GPIO1", 1, GPIO1_GPIO1},
{"GPIO1_NAND_CS0", 1, GPIO1_NAND_CS0},
{"GPIO2_GPIO2", 2, GPIO2_GPIO2},
{"GPIO2_NAND_READY", 2, GPIO2_NAND_READY},
{"GPIO3_GPIO3", 3, GPIO3_GPIO3},
{"GPIO3_NAND_CLE", 3, GPIO3_NAND_CLE},
{"GPIO3_SPIFC0_SCLK", 3, GPIO3_SPIFC0_SCLK},
{"GPIO4_GPIO4", 4, GPIO4_GPIO4},
{"GPIO4_NAND_ALE", 4, GPIO4_NAND_ALE},
{"GPIO5_GPIO5", 5, GPIO5_GPIO5},
{"GPIO5_NAND_RE", 5, GPIO5_NAND_RE},
{"GPIO5_SPIFC0_CS", 5, GPIO5_SPIFC0_CS},
{"GPIO6_GPIO6", 6, GPIO6_GPIO6},
{"GPIO6_NAND_WRITE_PROTECT",6,GPIO6_NAND_WRITE_PROTECT},
{"GPIO7_GPIO7", 7, GPIO7_GPIO7},
{"GPIO7_NAND_DATA0", 7, GPIO7_NAND_DATA0},
{"GPIO7_SSP1_CS", 7, GPIO7_SSP1_CS},
{"GPIO8_GPIO8", 8, GPIO8_GPIO8},
{"GPIO8_NAND_DATA1", 8, GPIO8_NAND_DATA1},
{"GPIO8_SSP1_CLK", 8, GPIO8_SSP1_CLK},
{"GPIO9_GPIO9", 9, GPIO9_GPIO9},
{"GPIO9_NAND_DATA2", 9, GPIO9_NAND_DATA2},
{"GPIO9_SPIFC0_DATA0", 9, GPIO9_SPIFC0_DATA0},
{"GPIO10_GPIO10", 10, GPIO10_GPIO10},
{"GPIO10_NAND_DATA3", 10, GPIO10_NAND_DATA3},
{"GPIO10_SPIFC0_DATA1", 10, GPIO10_SPIFC0_DATA1},
{"GPIO11_GPIO11", 11, GPIO11_GPIO11},
{"GPIO11_NAND_DATA4", 11, GPIO11_NAND_DATA4},
{"GPIO11_SPIFC0_DATA2", 11, GPIO11_SPIFC0_DATA2},
{"GPIO12_GPIO12", 12, GPIO12_GPIO12},
{"GPIO12_NAND_DATA5", 12, GPIO12_NAND_DATA5},
{"GPIO12_SPIFC0_DATA3", 12, GPIO12_SPIFC0_DATA3},
{"GPIO13_GPIO13", 13, GPIO13_GPIO13},
{"GPIO13_NAND_DATA6", 13, GPIO13_NAND_DATA6},
{"GPIO13_SSP1_RXD", 13, GPIO13_SSP1_RXD},
{"GPIO14_GPIO14", 14, GPIO14_GPIO14},
{"GPIO14_NAND_DATA7", 14, GPIO14_NAND_DATA7},
{"GPIO14_SSP1_TXD", 14, GPIO14_SSP1_TXD},
{"GPIO23_CLK_OUT0", 23, GPIO23_CLK_OUT0},
{"GPIO23_GPIO23", 23, GPIO23_GPIO23},
{"GPIO24_GPIO24", 24, GPIO24_GPIO24},
{"GPIO24_CLK_OUT1", 24, GPIO24_CLK_OUT1},
{"GPIO25_GPIO25", 25, GPIO25_GPIO25},
{"GPIO25_CLK_OUT2", 25, GPIO25_CLK_OUT2},
{"GPIO25_TEST_CLK_OUT", 25, GPIO25_TEST_CLK_OUT},
{"GPIO26_GPIO26", 26, GPIO26_GPIO26},
{"GPIO26_CLK_32K_OUT", 26, GPIO26_CLK_32K_OUT},
{"GPIO27_CLK_REQ0", 27, GPIO27_CLK_REQ0},
{"GPIO27_GPIO27", 27, GPIO27_GPIO27},
{"GPIO29_PWRCTRL1", 29, GPIO29_PWRCTRL1},
{"GPIO29_GPIO29", 29, GPIO29_GPIO29},
{"GPIO30_GPIO30", 30, GPIO30_GPIO30},
{"GPIO30_SSP0_CS", 30, GPIO30_SSP0_CS},
{"GPIO31_GPIO31", 31, GPIO31_GPIO31},
{"GPIO31_SSP0_CLK", 31, GPIO31_SSP0_CLK},
{"GPIO32_GPIO32", 32, GPIO32_GPIO32},
{"GPIO32_SSP0_RXD", 32, GPIO32_SSP0_RXD},
{"GPIO33_GPIO33", 33, GPIO33_GPIO33},
{"GPIO33_SSP0_TXD", 33, GPIO33_SSP0_TXD},
{"GPIO34_UART0_RXD", 34, GPIO34_UART0_RXD},
{"GPIO34_GPIO34", 34, GPIO34_GPIO34},
{"GPIO34_UART0_TXD", 34, GPIO34_UART0_TXD},
{"GPIO34_FRAME_SYNC", 34, GPIO34_FRAME_SYNC},
{"GPIO34_TEST_PIN10", 34, GPIO34_TEST_PIN10},
{"GPIO35_UART0_TXD", 35, GPIO35_UART0_TXD},
{"GPIO35_GPIO35", 35, GPIO35_GPIO35},
{"GPIO35_UART0_RXD", 35, GPIO35_UART0_RXD},
{"GPIO35_LTE_PRE_TX", 35, GPIO35_LTE_PRE_TX},
{"GPIO35_TEST_PIN11", 35, GPIO35_TEST_PIN11},
{"GPIO36_UART0_CTS", 36, GPIO36_UART0_CTS},
{"GPIO36_GPIO36", 36, GPIO36_GPIO36},
{"GPIO36_UART1_RXD", 36, GPIO36_UART1_RXD},
{"GPIO36_LTE_TPU_OUT3", 36, GPIO36_LTE_TPU_OUT3},
{"GPIO36_TEST_PIN12", 36, GPIO36_TEST_PIN12},
{"GPIO36_UART1_TXD", 36, GPIO36_UART1_TXD},
{"GPIO37_UART0_RTS", 37, GPIO37_UART0_RTS},
{"GPIO37_GPIO37", 37, GPIO37_GPIO37},
{"GPIO37_UART1_TXD", 37, GPIO37_UART1_TXD},
{"GPIO37_LTE_TPU_OUT4", 37, GPIO37_LTE_TPU_OUT4},
{"GPIO37_UART1_RXD", 37, GPIO37_UART1_RXD},
{"GPIO38_GPIO38", 38, GPIO38_GPIO38},
{"GPIO38_I2S0_WS", 38, GPIO38_I2S0_WS},
{"GPIO38_TEST_PIN0", 38, GPIO38_TEST_PIN0},
{"GPIO38_LTE_DATA_DONGLE_CLK", 38,GPIO38_LTE_DATA_DONGLE_CLK},
{"GPIO38_TDM_FS", 38, GPIO38_TDM_FS},
{"GPIO39_GPIO39", 39, GPIO39_GPIO39},
{"GPIO39_I2S0_CLK", 39, GPIO39_I2S0_CLK},
{"GPIO39_TEST_PIN1", 39, GPIO39_TEST_PIN1},
{"GPIO39_LTE_DATA_DONGLE_CMD", 39,GPIO39_LTE_DATA_DONGLE_CMD},
{"GPIO39_TDM_CLK", 39, GPIO39_TDM_CLK},
{"GPIO40_GPIO40", 40, GPIO40_GPIO40},
{"GPIO40_I2S0_DIN", 40, GPIO40_I2S0_DIN},
{"GPIO40_TEST_PIN2", 40, GPIO40_TEST_PIN2},
{"GPIO40_LTE_DATA_DONGLE0", 40, GPIO40_LTE_DATA_DONGLE0},
{"GPIO40_TDM_DATA_IN", 40, GPIO40_TDM_DATA_IN},
{"GPIO41_GPIO41", 41, GPIO41_GPIO41},
{"GPIO41_I2S0_DOUT", 41, GPIO41_I2S0_DOUT},
{"GPIO41_TEST_PIN3", 41, GPIO41_TEST_PIN3},
{"GPIO41_LTE_DATA_DONGLE1", 41, GPIO41_LTE_DATA_DONGLE1},
{"GPIO41_TDM_DATA_OUT", 41, GPIO41_TDM_DATA_OUT},
{"GPIO42_GPIO42", 42, GPIO42_GPIO42},
{"GPIO42_I2S1_WS", 42, GPIO42_I2S1_WS},
{"GPIO42_TEST_PIN4", 42, GPIO42_TEST_PIN4},
{"GPIO42_LTE_DATA_DONGLE2", 42, GPIO42_LTE_DATA_DONGLE2},
{"GPIO42_TDM_FS", 42, GPIO42_TDM_FS},
{"GPIO43_GPIO43", 43, GPIO43_GPIO43},
{"GPIO43_I2S1_CLK", 43, GPIO43_I2S1_CLK},
{"GPIO43_TEST_PIN5", 43, GPIO43_TEST_PIN5},
{"GPIO43_LTE_DATA_DONGLE3", 43, GPIO43_LTE_DATA_DONGLE3},
{"GPIO43_TDM_CLK", 43, GPIO43_TDM_CLK},
{"GPIO44_GPIO44", 44, GPIO44_GPIO44},
{"GPIO44_I2S1_DIN", 44, GPIO44_I2S1_DIN},
{"GPIO44_TEST_PIN6", 44, GPIO44_TEST_PIN6},
{"GPIO44_TDM_DATA_IN", 44, GPIO44_TDM_DATA_IN},
{"GPIO45_GPIO45", 45, GPIO45_GPIO45},
{"GPIO45_I2S1_DOUT", 45, GPIO45_I2S1_DOUT},
{"GPIO45_TEST_PIN7", 45, GPIO45_TEST_PIN7},
{"GPIO45_TDM_DATA_OUT", 45, GPIO45_TDM_DATA_OUT},
{"GPIO46_SCL0", 46, GPIO46_SCL0},
{"GPIO46_GPIO46", 46, GPIO46_GPIO46},
{"GPIO47_SDA0", 47, GPIO47_SDA0},
{"GPIO47_GPIO47", 47, GPIO47_GPIO47},
{"GPIO48_GPIO48", 48, GPIO48_GPIO48},
{"GPIO48_SCL1", 48, GPIO48_SCL1},
{"GPIO49_GPIO49", 49, GPIO49_GPIO49},
{"GPIO49_SDA1", 49, GPIO49_SDA1},
{"GPIO50_GPIO50", 50, GPIO50_GPIO50},
{"GPIO50_EXT_INT0", 50, GPIO50_EXT_INT0},
{"GPIO51_GPIO51", 51, GPIO51_GPIO51},
{"GPIO51_EXT_INT1", 51, GPIO51_EXT_INT1},
{"GPIO52_GPIO52", 52, GPIO52_GPIO52},
{"GPIO52_EXT_INT2", 52, GPIO52_EXT_INT2},
{"GPIO53_GPIO53", 53, GPIO53_GPIO53},
{"GPIO53_EXT_INT3", 53, GPIO53_EXT_INT3},
{"GPIO53_TEST_PIN8", 53, GPIO53_TEST_PIN8},
{"GPIO54_GPIO54", 54, GPIO54_GPIO54},
{"GPIO54_EXT_INT4", 54, GPIO54_EXT_INT4},
{"GPIO54_TEST_PIN9", 54, GPIO54_TEST_PIN9},
{"GPIO55_GPIO55", 55, GPIO55_GPIO55},
{"GPIO55_EXT_INT5", 55, GPIO55_EXT_INT5},
{"GPIO55_TEST_PIN13", 55, GPIO55_TEST_PIN13},
{"GPIO56_GPIO56", 56, GPIO56_GPIO56},
{"GPIO56_EXT_INT6", 56, GPIO56_EXT_INT6},
{"GPIO56_CLK_REQ1", 56, GPIO56_CLK_REQ1},
{"GPIO56_TEST_PIN14", 56, GPIO56_TEST_PIN14},
{"GPIO57_GPIO57", 57, GPIO57_GPIO57},
{"GPIO57_EXT_INT7", 57, GPIO57_EXT_INT7},
{"GPIO57_TEST_PIN15", 57, GPIO57_TEST_PIN15},
{"GPIO58_GPIO58", 58, GPIO58_GPIO58},
{"GPIO58_SD1_HOST_SDCLK", 58, GPIO58_SD1_HOST_SDCLK},
{"GPIO59_GPIO59", 59, GPIO59_GPIO59},
{"GPIO59_M_JTAG_TDO", 59, GPIO59_M_JTAG_TDO},
{"GPIO59_SD1_CMD", 59, GPIO59_SD1_CMD},
{"GPIO59_PS_JTAG_TDO", 59, GPIO59_PS_JTAG_TDO},
{"GPIO59_PHY_JTAG_TDO", 59, GPIO59_PHY_JTAG_TDO},
{"GPIO59_AP_JTAG_TDO", 59, GPIO59_AP_JTAG_TDO},
{"GPIO60_GPIO60", 60, GPIO60_GPIO60},
{"GPIO60_M_JTAG_TCK", 60, GPIO60_M_JTAG_TCK},
{"GPIO60_SD1_DATA0", 60, GPIO60_SD1_DATA0},
{"GPIO60_PS_JTAG_TCK", 60, GPIO60_PS_JTAG_TCK},
{"GPIO60_PHY_JTAG_TCK", 60, GPIO60_PHY_JTAG_TCK},
{"GPIO60_AP_JTAG_TCK", 60, GPIO60_AP_JTAG_TCK},
{"GPIO61_GPIO61", 61, GPIO61_GPIO61},
{"GPIO61_M_JTAG_TRST", 61, GPIO61_M_JTAG_TRST},
{"GPIO61_SD1_DATA1", 61, GPIO61_SD1_DATA1},
{"GPIO61_PS_JTAG_TRST", 61, GPIO61_PS_JTAG_TRST},
{"GPIO61_PHY_JTAG_TRST", 61, GPIO61_PHY_JTAG_TRST},
{"GPIO61_AP_JTAG_TRST", 61, GPIO61_AP_JTAG_TRST},
{"GPIO62_GPIO62", 62, GPIO62_GPIO62},
{"GPIO62_M_JTAG_TMS", 62, GPIO62_M_JTAG_TMS},
{"GPIO62_SD1_DATA2", 62, GPIO62_SD1_DATA2},
{"GPIO62_PS_JTAG_TMS", 62, GPIO62_PS_JTAG_TMS},
{"GPIO62_PHY_JTAG_TMS", 62, GPIO62_PHY_JTAG_TMS},
{"GPIO62_AP_JTAG_TMS", 62, GPIO62_AP_JTAG_TMS},
{"GPIO63_GPIO63", 63, GPIO63_GPIO63},
{"GPIO63_M_JTAG_TDI", 63, GPIO63_M_JTAG_TDI},
{"GPIO63_SD1_DATA2", 63, GPIO63_SD1_DATA2},
{"GPIO63_PS_JTAG_TDI", 63, GPIO63_PS_JTAG_TDI},
{"GPIO63_PHY_JTAG_TDI", 63, GPIO63_PHY_JTAG_TDI},
{"GPIO63_AP_JTAG_TDI", 63, GPIO63_AP_JTAG_TDI},
{"GPIO64_M_JTAG_TCK", 64, GPIO64_M_JTAG_TCK},
{"GPIO64_GPIO64", 64, GPIO64_GPIO64},
{"GPIO64_PS_JTAG_TCK", 64, GPIO64_PS_JTAG_TCK},
{"GPIO64_PHY_JTAG_TCK", 64, GPIO64_PHY_JTAG_TCK},
{"GPIO64_AP_JTAG_TCK", 64, GPIO64_AP_JTAG_TCK},
{"GPIO66_M_JTAG_TDI", 66, GPIO66_M_JTAG_TDI},
{"GPIO66_GPIO66", 66, GPIO66_GPIO66},
{"GPIO66_PS_JTAG_TDI", 66, GPIO66_PS_JTAG_TDI},
{"GPIO66_PHY_JTAG_TDI", 66, GPIO66_PHY_JTAG_TDI},
{"GPIO66_AP_JTAG_TDI", 66, GPIO66_AP_JTAG_TDI},
{"GPIO67_M_JTAG_TDO", 67, GPIO67_M_JTAG_TDO},
{"GPIO67_GPIO67", 67, GPIO67_GPIO67},
{"GPIO67_PS_JTAG_TDO", 67, GPIO67_PS_JTAG_TDO},
{"GPIO67_PHY_JTAG_TDO", 67, GPIO67_PHY_JTAG_TDO},
{"GPIO67_AP_JTAG_TDO", 67, GPIO67_AP_JTAG_TDO},
{"GPIO68_M_JTAG_TMS", 68, GPIO68_M_JTAG_TMS},
{"GPIO68_GPIO68", 68, GPIO68_GPIO68},
{"GPIO68_PS_JTAG_TMS", 68, GPIO68_PS_JTAG_TMS},
{"GPIO68_PHY_JTAG_TMS", 68, GPIO68_PHY_JTAG_TMS},
{"GPIO68_AP_JTAG_TMS", 68, GPIO68_AP_JTAG_TMS},
{"GPIO69_M_JTAG_TRST", 69, GPIO69_M_JTAG_TRST},
{"GPIO69_GPIO69", 69, GPIO69_GPIO69},
{"GPIO69_PS_JTAG_TRST", 69, GPIO69_PS_JTAG_TRST},
{"GPIO69_PHY_JTAG_TRST", 69, GPIO69_PHY_JTAG_TRST},
{"GPIO69_AP_JTAG_TRST", 69, GPIO69_AP_JTAG_TRST},
{"GPIO70_KEY_COL0", 70, GPIO70_KEY_COL0},
{"GPIO70_GPIO70", 70, GPIO70_GPIO70},
{"GPIO70_EXT_INT8", 70, GPIO70_EXT_INT8},
{"GPIO70_M_JTAG_TDO", 70, GPIO70_M_JTAG_TDO},
{"GPIO70_PS_JTAG_TDO", 70, GPIO70_PS_JTAG_TDO},
{"GPIO70_PHY_JTAG_TDO", 70, GPIO70_PHY_JTAG_TDO},
{"GPIO70_AP_JTAG_TDO", 70, GPIO70_AP_JTAG_TDO},
{"GPIO70_LTE_DATA_DONGLE4", 70, GPIO70_LTE_DATA_DONGLE4},
{"GPIO71_KEY_COL1", 71, GPIO71_KEY_COL1},
{"GPIO71_GPIO71", 71, GPIO71_GPIO71},
{"GPIO71_EXT_INT9", 71, GPIO71_EXT_INT9},
{"GPIO71_LTE_DATA_DONGLE5", 71, GPIO71_LTE_DATA_DONGLE5},
{"GPIO72_KEY_COL2", 72, GPIO72_KEY_COL2},
{"GPIO72_GPIO72", 72, GPIO72_GPIO72},
{"GPIO72_EXT_INT10", 72, GPIO72_EXT_INT10},
{"GPIO72_M_JTAG_TCK", 72, GPIO72_M_JTAG_TCK},
{"GPIO72_PS_JTAG_TCK", 72, GPIO72_PS_JTAG_TCK},
{"GPIO72_PHY_JTAG_TCK", 72, GPIO72_PHY_JTAG_TCK},
{"GPIO72_AP_JTAG_TCK", 72, GPIO72_AP_JTAG_TCK},
{"GPIO72_LTE_DATA_DONGLE6", 72, GPIO72_LTE_DATA_DONGLE6},
{"GPIO73_KEY_COL3", 73, GPIO73_KEY_COL3},
{"GPIO73_GPIO73", 73, GPIO73_GPIO73},
{"GPIO73_EXT_INT11", 73, GPIO73_EXT_INT11},
{"GPIO73_LTE_DATA_DONGLE7", 73, GPIO73_LTE_DATA_DONGLE7},
{"GPIO74_KEY_ROW0", 74, GPIO74_KEY_ROW0},
{"GPIO74_GPIO74", 74, GPIO74_GPIO74},
{"GPIO74_EXT_INT12", 74, GPIO74_EXT_INT12},
{"GPIO74_M_JTAG_TRST", 74, GPIO74_M_JTAG_TRST},
{"GPIO74_PS_JTAG_TRST", 74, GPIO74_PS_JTAG_TRST},
{"GPIO74_PHY_JTAG_TRST", 74, GPIO74_PHY_JTAG_TRST},
{"GPIO74_AP_JTAG_TRST", 74, GPIO74_AP_JTAG_TRST},
{"GPIO74_LTE_DATA_DONGLE8", 74, GPIO74_LTE_DATA_DONGLE8},
{"GPIO75_KEY_ROW1", 75, GPIO75_KEY_ROW1},
{"GPIO75_GPIO75", 75, GPIO75_GPIO75},
{"GPIO75_EXT_INT13", 75, GPIO75_EXT_INT13},
{"GPIO75_M_JTAG_TMS", 75, GPIO75_M_JTAG_TMS},
{"GPIO75_PS_JTAG_TMS", 75, GPIO75_PS_JTAG_TMS},
{"GPIO75_PHY_JTAG_TMS", 75, GPIO75_PHY_JTAG_TMS},
{"GPIO75_AP_JTAG_TMS", 75, GPIO75_AP_JTAG_TMS},
{"GPIO75_LTE_DATA_DONGLE9", 75, GPIO75_LTE_DATA_DONGLE9},
{"GPIO76_KEY_ROW2", 76, GPIO76_KEY_ROW2},
{"GPIO76_GPIO76", 76, GPIO76_GPIO76},
{"GPIO76_EXT_INT14", 76, GPIO76_EXT_INT14},
{"GPIO76_M_JTAG_TDI", 76, GPIO76_M_JTAG_TDI},
{"GPIO76_PS_JTAG_TDI", 76, GPIO76_PS_JTAG_TDI},
{"GPIO76_PHY_JTAG_TDI", 76, GPIO76_PHY_JTAG_TDI},
{"GPIO76_AP_JTAG_TDI", 76, GPIO76_AP_JTAG_TDI},
{"GPIO76_UART2_RXD", 76, GPIO76_UART2_RXD},
{"GPIO77_KEY_ROW3", 77, GPIO77_KEY_ROW3},
{"GPIO77_GPIO77", 77, GPIO77_GPIO77},
{"GPIO77_EXT_INT15", 77, GPIO77_EXT_INT15},
{"GPIO77_UART2_TXD", 77, GPIO77_UART2_TXD},
{"GPIO78_GPIO78", 78, GPIO78_GPIO78},
{"GPIO78_MODEM_TXRX_DATA0", 78, GPIO78_MODEM_TXRX_DATA0},
{"GPIO79_GPIO79", 79, GPIO79_GPIO79},
{"GPIO79_MODEM_TXRX_DATA1", 79, GPIO79_MODEM_TXRX_DATA1},
{"GPIO80_GPIO80", 80, GPIO80_GPIO80},
{"GPIO80_MODEM_TXRX_DATA2", 80, GPIO80_MODEM_TXRX_DATA2},
{"GPIO81_GPIO81", 81, GPIO81_GPIO81},
{"GPIO81_MODEM_TXRX_DATA3", 81, GPIO81_MODEM_TXRX_DATA3},
{"GPIO82_GPIO82", 82, GPIO82_GPIO82},
{"GPIO82_MODEM_TXRX_DATA4", 82, GPIO82_MODEM_TXRX_DATA4},
{"GPIO83_GPIO83", 83, GPIO83_GPIO83},
{"GPIO83_MODEM_TXRX_DATA5", 83, GPIO83_MODEM_TXRX_DATA5},
{"GPIO84_GPIO84", 84, GPIO84_GPIO84},
{"GPIO84_MODEM_TXRX_DATA6", 84, GPIO84_MODEM_TXRX_DATA6},
{"GPIO85_GPIO85", 85, GPIO85_GPIO85},
{"GPIO85_MODEM_TXRX_DATA7", 85, GPIO85_MODEM_TXRX_DATA7},
{"GPIO86_GPIO86", 86, GPIO86_GPIO86},
{"GPIO86_MODEM_TXRX_DATA8", 86, GPIO86_MODEM_TXRX_DATA8},
{"GPIO87_GPIO87", 87, GPIO87_GPIO87},
{"GPIO87_MODEM_TXRX_DATA9", 87, GPIO87_MODEM_TXRX_DATA9},
{"GPIO88_GPIO88", 88, GPIO88_GPIO88},
{"GPIO88_MODEM_TXRX_DATA10", 88, GPIO88_MODEM_TXRX_DATA10},
{"GPIO89_GPIO89", 89, GPIO89_GPIO89},
{"GPIO89_MODEM_TXRX_DATA11", 89, GPIO89_MODEM_TXRX_DATA11},
{"GPIO90_GPIO90", 90, GPIO90_GPIO90},
{"GPIO90_MODEM_RX_DATA0", 90, GPIO90_MODEM_RX_DATA0},
{"GPIO91_GPIO91", 91, GPIO91_GPIO91},
{"GPIO91_MODEM_RX_DATA1", 91, GPIO91_MODEM_RX_DATA1},
{"GPIO92_GPIO92", 92, GPIO92_GPIO92},
{"GPIO92_MODEM_RX_DATA2", 92, GPIO92_MODEM_RX_DATA2},
{"GPIO93_GPIO93", 93, GPIO93_GPIO93},
{"GPIO93_MODEM_RX_DATA3", 93, GPIO93_MODEM_RX_DATA3},
{"GPIO94_GPIO94", 94, GPIO94_GPIO94},
{"GPIO94_MODEM_RX_DATA4", 94, GPIO94_MODEM_RX_DATA4},
{"GPIO95_GPIO95", 95, GPIO95_GPIO95},
{"GPIO95_MODEM_RX_DATA5", 95, GPIO95_MODEM_RX_DATA5},
{"GPIO96_GPIO96", 96, GPIO96_GPIO96},
{"GPIO96_MODEM_RX_DATA6", 96, GPIO96_MODEM_RX_DATA6},
{"GPIO97_GPIO97", 97, GPIO97_GPIO97},
{"GPIO97_MODEM_RX_DATA7", 97, GPIO97_MODEM_RX_DATA7},
{"GPIO98_GPIO98", 98, GPIO98_GPIO98},
{"GPIO98_MODEM_RX_DATA8", 98, GPIO98_MODEM_RX_DATA8},
{"GPIO99_GPIO99", 99, GPIO99_GPIO99},
{"GPIO99_MODEM_RX_DATA9", 99, GPIO99_MODEM_RX_DATA9},
{"GPIO100_GPIO100", 100, GPIO100_GPIO100},
{"GPIO100_MODEM_RX_DATA10", 100, GPIO100_MODEM_RX_DATA10},
{"GPIO101_GPIO101", 101, GPIO101_GPIO101},
{"GPIO101_MODEM_RX_DATA11", 101, GPIO101_MODEM_RX_DATA11},
{"GPIO102_GPIO102", 102, GPIO102_GPIO102},
{"GPIO102_MODEM_FCLK_O", 102, GPIO102_MODEM_FCLK_O},
{"GPIO103_GPIO103", 103, GPIO103_GPIO103},
{"GPIO103_MODEM_FRAME_TX_O", 103, GPIO103_MODEM_FRAME_TX_O},
{"GPIO104_GPIO104", 104, GPIO104_GPIO104},
{"GPIO104_MODEM_FRAME_RX_I", 104, GPIO104_MODEM_FRAME_RX_I},
{"GPIO105_GPIO105", 105, GPIO105_GPIO105},
{"GPIO105_MODEM_MCLK_I", 105, GPIO105_MODEM_MCLK_I},
{"GPIO106_GPIO106", 106, GPIO106_GPIO106},
{"GPIO106_LTE_REF_CLK", 106, GPIO106_LTE_REF_CLK},
{"GPIO109_GPIO109", 109, GPIO109_GPIO109},
{"GPIO110_GPIO110", 110, GPIO110_GPIO110},
{"GPIO110_GSM_OUT_OLD_O_12", 110, GPIO110_GSM_OUT_OLD_O_12},
{"GPIO111_PWRCTRL2", 111, GPIO111_PWRCTRL2},
{"GPIO111_GPIO111", 111, GPIO111_GPIO111},
{"GPIO112_GPIO112", 112, GPIO112_GPIO112},
{"GPIO112_RF_SPI0_STR0", 112, GPIO112_RF_SPI0_STR0},
{"GPIO113_GPIO113", 113, GPIO113_GPIO113},
{"GPIO113_RF_SPI0_STR1", 113, GPIO113_RF_SPI0_STR1},
{"GPIO114_GPIO114", 114, GPIO114_GPIO114},
{"GPIO114_RF_SPI0_CLK", 114, GPIO114_RF_SPI0_CLK},
{"GPIO115_GPIO115", 115, GPIO115_GPIO115},
{"GPIO115_RF_SPI0_DIN", 115, GPIO115_RF_SPI0_DIN},
{"GPIO116_GPIO116", 116, GPIO116_GPIO116},
{"GPIO116_RF_SPI0_DATA", 116, GPIO116_RF_SPI0_DATA},
{"GPIO117_GPIO117", 117, GPIO117_GPIO117},
{"GPIO117_RF_SPI1_STR0", 117, GPIO117_RF_SPI1_STR0},
{"GPIO118_GPIO118", 118, GPIO118_GPIO118},
{"GPIO118_RF_SPI1_CLK", 118, GPIO118_RF_SPI1_CLK},
{"GPIO119_GPIO119", 119, GPIO119_GPIO119},
{"GPIO119_RF_SPI1_DIN", 119, GPIO119_RF_SPI1_DIN},
{"GPIO120_GPIO120", 120, GPIO120_GPIO120},
{"GPIO120_RF_SPI1_DATA", 120, GPIO120_RF_SPI1_DATA},
{"GPIO145_GPIO145", 145, GPIO145_GPIO145},
{"GPIO145_RMII_TXEN", 145, GPIO145_RMII_TXEN},
{"GPIO146_GPIO146", 146, GPIO146_GPIO146},
{"GPIO146_RMII_RXEN", 146, GPIO146_RMII_RXEN},
{"GPIO147_GPIO147", 147, GPIO147_GPIO147},
{"GPIO147_RMII_RXD0", 147, GPIO147_RMII_RXD0},
{"GPIO148_GPIO148", 148, GPIO148_GPIO148},
{"GPIO148_RMII_RXD1", 148, GPIO148_RMII_RXD1},
{"GPIO149_GPIO149", 149, GPIO149_GPIO149},
{"GPIO149_RMII_TXD0", 149, GPIO149_RMII_TXD0},
{"GPIO150_GPIO150", 150, GPIO150_GPIO150},
{"GPIO150_RMII_TXD1", 150, GPIO150_RMII_TXD1},
{"GPIO151_GPIO151", 151, GPIO151_GPIO151},
{"GPIO151_MDC_SCLK", 151, GPIO151_MDC_SCLK},
{"GPIO152_GPIO152", 152, GPIO152_GPIO152},
{"GPIO152_MDC_SDIO", 152, GPIO152_MDC_SDIO},
{"GPIO153_GPIO153", 153, GPIO153_GPIO153},
{"GPIO153_PHY_RST", 153, GPIO153_PHY_RST},
{"GPIO154_GPIO154", 154, GPIO154_GPIO154},
{"GPIO154_RMII_CLK_O", 154, GPIO154_RMII_CLK_O},
{"GPIO155_GPIO155", 155, GPIO155_GPIO155},
{"GPIO155_RMII_CLK_I", 155, GPIO155_RMII_CLK_I},
{"GPIO FUNCTION NOT EXIST", 255, ZX29_GPIO_NULL},
};
void zx29_gpio_status_get(unsigned int gpio)
{
int temp = 0, n = 0;
temp = zx29_gpio_function_sel_get(gpio);
for(n=0; n<ARRAY_SIZE(gpio_def); n++)
{
if(gpio_def[n].gpio_func == temp)
{
gpio_status_get.function = gpio_def[n].gpio_name;
break;
}
if(gpio_def[n].gpio_num == ZX29_GPIO_NULL)
{
printk("GPIO%d function not exist, func[%d]\n",gpio,temp);
gpio_status_get.function = gpio_def[n].gpio_name;
}
}
temp=zx29_gpio_get_direction(gpio);
if(temp==GPIO_IN)
{
gpio_status_get.direction = "GPIO_IN";
temp=zx29_gpio_input_data(gpio);
if(temp)
gpio_status_get.level = "GPIO_HIGH";
else
gpio_status_get.level = "GPIO_LOW";
}
else
{
gpio_status_get.direction = "GPIO_OUT";
temp=zx29_gpio_outputdata_get(gpio);
if(temp)
gpio_status_get.level = "GPIO_HIGH";
else
gpio_status_get.level = "GPIO_LOW";
}
}
/*sectionally get gpio seting parameters in temp_buf[50] */
static void temp_buf_get(void)
{
unsigned char n = 0;
while((temp_buf[buf] != ' ')&&(temp_buf[buf] != '#')&&(temp_buf[buf] != '\0'))
{
temp[n++] = temp_buf[buf++];
}
temp[n] = '\0';
buf++;
}
/* analysis seting parameters in temp_buf[50] to get setting parameters of gpio_num,gpio_function, gpio_dir and gpio_level */
static int parse_temp_buf(char *tempbuf)
{
unsigned gpio_num = 0, gpio_dir = 0,gpio_level = 0;
unsigned int gpio_func = 0,n = 0;
unsigned char temp_k = 0, gpio_flag = 1;
int ret = 0;
buf = 0;
/* get function setting parameters in"GPIO40_LTE_DATA_DONGLE0 OUT HIGH#"*/
temp_buf_get();
for(n=0; n<ARRAY_SIZE(gpio_def); n++)
{
if(!strcmp(gpio_def[n].gpio_name,temp))
{
gpio_num = gpio_def[n].gpio_num;
gpio_func = gpio_def[n].gpio_func;
break;
}
if(!strcmp(gpio_def[n].gpio_name ,"GPIO FUNCTION NOT EXIST"))
{
printk("gpio_func INVALID INPUT\n");
return -EINVAL;
}
}
ret = zx29_gpio_function_sel(gpio_num, gpio_func);
if(ret)
return ret;
/*juge gpio is used as GPIO (GPIO40_GPIO40,the two strings besides the '_' are same) or multiplex function */
temp_k = (strlen(temp)-1)/2;
for(n=0;n<temp_k;n++)
{
if(temp[n] != temp[temp_k+1+n])
{
gpio_flag = 0;
break;
}
}
if(!gpio_flag)
return 0;
/* get direction setting parameters in"GPIO40_LTE_DATA_DONGLE0 OUT HIGH#"*/
temp_buf_get();
if(!strcmp(temp,""))/*just set GPIO function*/
return 0;
else if(!strcmp(temp,"IN"))
gpio_dir = GPIO_IN;
else if(!strcmp(temp,"OUT"))
gpio_dir = GPIO_OUT;
else
{
printk("gpio_dir INVALID INPUT\n");
return -EINVAL;
}
zx29_gpio_set_direction(gpio_num,gpio_dir);
if(gpio_dir == GPIO_IN)
return 0;
/* get level setting parameters in"GPIO40_LTE_DATA_DONGLE0 OUT HIGH#"*/
temp_buf_get();
if(!strcmp(temp,"HIGH"))
gpio_level = GPIO_HIGH;
else if(!strcmp(temp,"LOW"))
gpio_level = GPIO_LOW;
else
{
printk("gpio_level INVALID INPUT\n");
return -EINVAL;
}
zx29_gpio_output_data(gpio_num,gpio_level);
return 0;
}
unsigned int gpio_param_valid(unsigned int num)
{
unsigned int n,valid = 0;
for(n=0; n<ARRAY_SIZE(pin_info); n++)
{ if(pin_info[n].gpio == num)
{
valid = 1;
break;
}
}
return valid;
}
static int dbg_gpio_show(struct seq_file *s, void *unused)
{
unsigned int num;
seq_printf(s,"The gpio module status:\n");
for(num = 0; num <= ZX29_GPIO_MAX; num++)
{
if(gpio_param_valid(num))
{
zx29_gpio_status_get(num);
seq_printf(s,"%-30s",gpio_status_get.function);
seq_printf(s,"%-15s",gpio_status_get.direction);
seq_printf(s,"%-15s\n",gpio_status_get.level);
}
}
return 0;
}
ssize_t gpio_debug_write (struct file *file, const char __user *buf, size_t size, loff_t *p)
{
int ret;
if(copy_from_user(temp_buf, buf, size))
printk("copy user failed\n");
/*parse temp_buf*/
ret=parse_temp_buf(temp_buf);
if(!ret)
printk("GPIO setting succeed\n");
else
{
printk("GPIO setting failed\n");
printk("please follow the format to input GPIO parameters :\"GPIO40_GPI40 OUT HIGH#\"\n");
}
return size;
}
static int dbg_gpio_open(struct inode *inode, struct file *file)
{
return single_open(file, dbg_gpio_show, &inode->i_private);
}
static const struct file_operations debug_fops = {
.open = dbg_gpio_open,
.read = seq_read,
.write = gpio_debug_write,
.llseek = seq_lseek,
.release = single_release,
};
static void zx29_gpio_debuginit(void)
{
(void) debugfs_create_file("zx29_gpio", S_IRUGO,
NULL, NULL, &debug_fops);
}
late_initcall(zx29_gpio_debuginit);
#endif