/***************************************************************************** * 函 数 名 : bsp_gpio_direction_get * * 功能描述 : 查询GPIO 引脚的方向 * * 输入参数 : UINT32 gpio GPIO引脚编号 * * 返 回 值 : 返回gpio引脚方向,即0为输入,1为输出 * * 修改记录 : 2012年11月27日 *****************************************************************************/ s32 bsp_gpio_direction_get(u32 gpio) { u32 chip_num; u32 pin; u32 u32GpioAddr = 0; u32 gpio_value = 0; /* 如果GPIO 没有初始化,返回错误 */ if (GPIO_DEF_NOT_RUNNING == g_u32GpioRunning) { gpio_print_error(" GPIO is not inited.\n"); return GPIO_ERROR; } if(gpio >= (u32)GPIO_TOTAL_PINS_NUM) { gpio_print_error(" GPIO parameter error.\n"); return GPIO_ERROR; } chip_num = gpio / (u32)GPIO_MAX_PINS; pin = gpio % (u32)GPIO_MAX_PINS; if(chip_num < GPIO_MAX_BANK_NUM){ u32GpioAddr = s_u32GpioBaseAddr[chip_num]; } else{ gpio_print_error(" GPIO bank number error.\n"); return GPIO_ERROR; } gpio_value = readl(u32GpioAddr + HI_GPIO_SWPORT_DDR_OFFSET); return (s32)((gpio_value & ((u32)0x1 << pin)) >> pin); }
/* read gpio expander reg */ int gpio_expander_register_debug(unsigned int num, int reg) { int ret; struct i2c_client *client = NULL; if(num >= GPIO_I2C_EXPANDER_NUM || (reg >= 8)) { gpio_print_error("para is error, num = %d, reg = 0x%x.\n", num, reg); return -1; } client = gpio_expander_client[num]; if (num < 2) ret = i2c_smbus_read_byte_data(client, reg); else ret = i2c_smbus_read_word_data(client, reg << 1); if (ret < 0) { gpio_print_error("failed reading register.\n"); return ret; } gpio_print_info("reg(0x%x) is 0x%x.\n", reg, ret); return 0; }
/***************************************************************************** * 函 数 名 : bsp_gpio_set_value * * 功能描述 : 设置GPIO 引脚的电平值 * * 输入参数 : u32 gpio GPIO引脚编号 * u32 value 管脚高/低电平 * * 返 回 值 : 无 * * 修改记录 : 2012年11月27日 *****************************************************************************/ void bsp_gpio_set_value(u32 gpio,u32 value) { u32 chip_num; u32 pin; u32 u32GpioAddr = 0; u32 gpio_value = 0; unsigned long irq_flags; /* 如果GPIO 没有初始化,返回错误 */ if (GPIO_DEF_NOT_RUNNING == g_u32GpioRunning) { gpio_print_error(" GPIO is not inited.\n"); return ; } if(gpio >= GPIO_TOTAL_PINS_NUM) { gpio_print_error(" GPIO parameter error.\n"); return; } /*检测GPIO方向是否输出,如果为输入,则返回错误*/ if(0 == bsp_gpio_direction_get(gpio)) { gpio_print_error(" GPIO direction error.\n"); return; } chip_num = gpio / (u32)GPIO_MAX_PINS; pin = gpio % (u32)GPIO_MAX_PINS; if(chip_num < GPIO_MAX_BANK_NUM){ u32GpioAddr = s_u32GpioBaseAddr[chip_num]; } else{ gpio_print_error(" GPIO bank number error.\n"); return ; } spin_lock_irqsave(&g_gpio_spinlock, irq_flags); (void)bsp_ipc_spin_lock(IPC_SEM_GPIO); gpio_value = readl(u32GpioAddr + HI_GPIO_SWPORT_DR_OFFSET); if(!!value) { writel(gpio_value | ((u32)0x1 << pin), u32GpioAddr + HI_GPIO_SWPORT_DR_OFFSET); } else { writel(gpio_value & ~((u32)0x1 << pin), u32GpioAddr + HI_GPIO_SWPORT_DR_OFFSET); } (void)bsp_ipc_spin_unlock(IPC_SEM_GPIO); spin_unlock_irqrestore(&g_gpio_spinlock, irq_flags); }
/***************************************************************************** * 函 数 名 : bsp_gpio_init * * 功能描述 : GPIO初始化接口 * * 输入参数 : 无 * * 返 回 值 : 无 * * 修改记录 : 2012年11月27日 *****************************************************************************/ s32 bsp_gpio_init(void) { u32 i = 0; int ret = 0; char gpio_clk_name[40] = ""; char node_name[NAME_LENTH] = ""; char *base_addr = NULL; struct clk *gpio_clk = NULL; struct device_node *dev_node = NULL; if (GPIO_DEF_RUNNING == g_u32GpioRunning) { return GPIO_OK; } spin_lock_init(&g_gpio_spinlock); for(i = 0; i < GPIO_MAX_BANK_NUM; i++) { (void)snprintf_s(node_name,NAME_LENTH,NAME_LENTH,"hisilicon,gpio%d",i); dev_node = of_find_compatible_node(NULL,NULL,node_name); if(!dev_node) { gpio_print_error("get gpio%d node failed!\n",i); return ERROR; } /* 内存映射,获得基址 */ base_addr = (char *)of_iomap(dev_node, 0); if (NULL == base_addr) { gpio_print_error("gpio%d iomap fail\n",i); return ERROR; } s_u32GpioBaseAddr[i] = (u32)base_addr; (void)memset_s(gpio_clk_name, 40, 0 , 40); (void)snprintf_s(gpio_clk_name, 40, 40, "gpio%d_clk", i); /*lint !e119*/ gpio_clk = (struct clk *)clk_get(NULL, gpio_clk_name); if(IS_ERR(gpio_clk)) { gpio_print_error("gpio%d clk cannot get, 0x%x.\n", i, gpio_clk); return ERROR; } ret = clk_enable(gpio_clk); } gpio_print_info("gpio init ok.\n"); g_u32GpioRunning = GPIO_DEF_RUNNING; return ret; }
void bsp_gpio_direction_output(u32 gpio, u32 value) { unsigned int gpio_base_addr = 0; unsigned int gpio_number = 0; unsigned int reg_value_old = 0; unsigned int reg_value_new = 0; if(value > 1 || gpio > GPIO_TOTAL) { gpio_print_error("para is error, gpio = %d, value = %d.\n", gpio, value); return ; } gpio_base_addr = get_gpio_base_addr(gpio); gpio_number = get_gpio_number(gpio); reg_value_old = readl(gpio_base_addr + GPIODIR); reg_value_new = (((unsigned int)0x1 << gpio_number)) | (reg_value_old); writel(reg_value_new, gpio_base_addr + GPIODIR); bsp_gpio_set_value( gpio, value); }
s32 bsp_gpio_init(void) { /* 天线选择NV初始化 */ if(0 != bsp_rf_switch_init()) { gpio_print_error("bsp_rf_switch_init is fail.\n"); } /* RF LDO NV初始化 */ if(0 != bsp_ldo_gpio_init()) { gpio_print_error("bsp_rf_switch_init is fail.\n"); return -1; } return 0; }
s32 bsp_gpio_direction_get(u32 gpio) { unsigned int gpio_base_addr, gpio_number; if(gpio > GPIO_TOTAL) { gpio_print_error("para is error, gpio = %d.\n", gpio); return -1; } gpio_number = get_gpio_number(gpio); if (gpio_number >= GPIO_MAX_NUMBER) { gpio_print_error("para is error, gpio = %d.\n", gpio); return -1; } gpio_base_addr = get_gpio_base_addr(gpio); unsigned int reg_value = readl(gpio_base_addr + GPIODIR); return (reg_value >> gpio_number) & 0x01; }
/*i2c gpio expander*/ static int __devinit gpio_i2c_expander_init(void) { unsigned int i = 0; struct i2c_adapter *adapter = NULL; //gpio_i2c_expander_reset();/* just for v7r2 test*/ adapter = i2c_get_adapter(GPIO_I2C_EXPANDER_ADP); if (!adapter) { gpio_print_error("i2c_get_adapter failed.\n"); return -1; } for(i = 0;i < GPIO_I2C_EXPANDER_NUM;i++) { gpio_expander_client[i] = i2c_new_device(adapter, &expander_board_info[i]); if (!gpio_expander_client[i]) { gpio_print_error("i2c_new_device failed, i = %d, addr = 0x%x.\n", i, expander_board_info[i].addr); return -1; } } #if 0 ret = i2c_register_board_info(GPIO_I2C_EXPANDER_ADP, expander_board_info, sizeof(expander_board_info)/sizeof(struct i2c_board_info)); if(ret < 0) { gpio_print_error("i2c_register_board_info is fail,ret = %d.\n", ret); return -1; } #endif gpio_print_info("gpio ex init ok.\n"); return 0; }
void bsp_gpio_set_value(u32 gpio,u32 value) { u32 gpio_base_addr = 0; u32 gpio_number = 0; u32 gpio_data_reg = 0; if(value > 1 || (gpio > GPIO_TOTAL)) { gpio_print_error("para is error, gpio = %d, value = %d.\n", gpio, value); return ; } gpio_base_addr = get_gpio_base_addr(gpio); gpio_number = get_gpio_number(gpio); gpio_data_reg = ((unsigned int)0x1 << (gpio_number + 2)); writel(value << gpio_number, gpio_base_addr + gpio_data_reg); }
/* just for v7r2 test */ void gpio_i2c_expander_reset(void) { int ret = 0; ret = gpio_request(GPIO_1_24, "gpio_expander"); if(ret < 0) { gpio_print_error( "gpio_request is fail, ret = %d.\n", ret); return ; } gpio_direction_output(GPIO_1_24, 0); mdelay(10); gpio_direction_output(GPIO_1_24, 1); }
int gpio_i2c_expander_setup(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context) { int ret = 0; unsigned int i = 0; for(i = 0;i < ngpio;i++) { ret = gpio_request(gpio + i, "gpio_expander"); if(ret < 0) { gpio_print_error( "gpio%d request is fail, ret = %d.\n", gpio + i, ret); return -1; } } return 0; }
s32 bsp_gpio_get_value(u32 gpio) { s32 value = 0; u32 gpio_base_addr = 0; u32 gpio_number = 0; u32 gpio_data_reg = 0; if(gpio > GPIO_TOTAL) { gpio_print_error("para is error, gpio = %d.\n", gpio); return -1; } gpio_base_addr = get_gpio_base_addr(gpio); gpio_number = get_gpio_number(gpio); gpio_data_reg = ((unsigned int)0x1 << (gpio_number + 2)); value = (s32)(readl(gpio_base_addr + gpio_data_reg) >> gpio_number); return value; }