/* * gpio/na51000_gpio.c * * Author: Howard Chang * Created: July 3, 2018 * Copyright: Novatek Inc. * */ #include #include #include #include #include #include struct nvt_gpio_bank { phys_addr_t base; }; #define GPIO_GETREG(ofs) INW(IOADDR_GPIO_REG_BASE+(ofs)) #define GPIO_SETREG(ofs, value) OUTW(IOADDR_GPIO_REG_BASE +(ofs),(value)) #define NVT_GPIO_STG_DATA_0 (0) #define NVT_GPIO_STG_DIR_0 (0x20) #define NVT_GPIO_STG_SET_0 (0x40) #define NVT_GPIO_STG_CLR_0 (0x60) static int gpio_validation(unsigned pin) { if ((pin < C_GPIO(0)) || (pin > C_GPIO(22) && pin < P_GPIO(0)) || \ (pin > P_GPIO(25) && pin < S_GPIO(0)) || \ (pin > S_GPIO(12) && pin < L_GPIO(0)) || \ (pin > L_GPIO(24) && pin < D_GPIO(0)) || \ (pin > D_GPIO(10) && pin < H_GPIO(0)) || \ (pin > H_GPIO(11) && pin < A_GPIO(0)) || (pin > A_GPIO(2))) { debug("The gpio number is out of range\n"); return E_NOSPT; } else return 0; } static int nvt_gpio_direction_input(struct udevice *dev, unsigned offset) { u32 reg_data; u32 ofs = (offset >> 5) << 2; if (gpio_validation(offset) < 0) return E_NOSPT; offset &= (32-1); reg_data = GPIO_GETREG(NVT_GPIO_STG_DIR_0 + ofs); reg_data &= ~(1<> 5) << 2; if (gpio_validation(offset) < 0) return E_NOSPT; offset &= (32-1); tmp = (1<> 5) << 2; if (gpio_validation(offset) < 0) return E_NOSPT; offset &= (32-1); tmp = (1<> 5) << 2; if (gpio_validation(offset) < 0) return E_NOSPT; offset &= (32-1); tmp = (1<> 5) << 2; if (gpio_validation(offset) < 0) return E_NOSPT; offset &= (32-1); reg_data = GPIO_GETREG(NVT_GPIO_STG_DIR_0 + ofs); if (reg_data & (1<gpio_count = 256; uc_priv->bank_name = "nvt-gpio"; return 0; } static const struct udevice_id nvt_gpio_ids[] = { { .compatible = "nvt,nvt_gpio" }, { } }; U_BOOT_DRIVER(gpio_msm) = { .name = "gpio_nvt", .id = UCLASS_GPIO, .of_match = nvt_gpio_ids, .ofdata_to_platdata = nvt_gpio_ofdata_to_platdata, .probe = nvt_gpio_probe, .ops = &gpio_nvt_ops, .priv_auto_alloc_size = sizeof(struct nvt_gpio_bank), };