/* * gpio/na51090_gpio.c * * Author: Howard Chang * Created: Dec 2, 2020 * 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 (0x30) #define NVT_GPIO_STG_SET_0 (0x60) #define NVT_GPIO_STG_CLR_0 (0x90) static int gpio_validation(unsigned pin) { if ((pin < C_GPIO(0)) || (pin > C_GPIO(13) && pin < J_GPIO(0)) || \ (pin > J_GPIO(5) && pin < P_GPIO(0)) || \ (pin > P_GPIO(44) && pin < E_GPIO(0)) || \ (pin > E_GPIO(31) && pin < D_GPIO(0)) || \ (pin > D_GPIO(11) && pin < S_GPIO(0)) || \ (pin > S_GPIO(83) && pin < B_GPIO(0)) || (pin > B_GPIO(16))) { 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) { unsigned long reg_data; unsigned long 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), };