/* SPDX-License-Identifier: GPL-2.0-only OR MIT */

/*
 * This file is created based on MT8196 Functional Specification
 * Chapter number: 13.4
 */

#include <device/mmio.h>
#include <gpio.h>

static const struct gpio_drv_info gpio_driving_info[] = {
	[0] = { 0x00, 0, 3, },
	[1] = { 0x00, 3, 3, },
	[2] = { 0x00, 12, 3, },
	[3] = { 0x00, 12, 3, },
	[4] = { 0x00, 15, 3, },
	[5] = { 0x00, 0, 3, },
	[6] = { 0x00, 3, 3, },
	[7] = { 0x00, 6, 3, },
	[8] = { 0x00, 9, 3, },
	[9] = { 0x10, 9, 3, },
	[10] = { 0x10, 6, 3, },
	[11] = { 0x00, 24, 3, },
	[12] = { 0x10, 15, 3, },
	[13] = { 0x00, 9, 3, },
	[14] = { 0x00, 0, 3, },
	[15] = { 0x00, 0, 3, },
	[16] = { 0x00, 9, 3, },
	[17] = { 0x00, 9, 3, },
	[18] = { 0x00, 3, 3, },
	[19] = { 0x00, 6, 3, },
	[20] = { 0x00, 9, 3, },
	[21] = { 0x00, 0, 3, },
	[22] = { 0x00, 3, 3, },
	[23] = { 0x00, 6, 3, },
	[24] = { 0x00, 9, 3, },
	[25] = { 0x00, 12, 3, },
	[26] = { 0x00, 15, 3, },
	[27] = { 0x10, 3, 3, },
	[28] = { 0x00, 18, 3, },
	[29] = { 0x00, 21, 3, },
	[30] = { 0x00, 24, 3, },
	[31] = { 0x00, 27, 3, },
	[32] = { 0x00, 21, 3, },
	[33] = { 0x00, 21, 3, },
	[34] = { 0x00, 21, 3, },
	[35] = { 0x00, 21, 3, },
	[36] = { 0x00, 21, 3, },
	[37] = { 0x00, 27, 3, },
	[38] = { 0x00, 18, 3, },
	[39] = { 0x00, 27, 3, },
	[40] = { 0x00, 6, 3, },
	[41] = { 0x00, 12, 3, },
	[42] = { 0x00, 9, 3, },
	[43] = { 0x00, 15, 3, },
	[44] = { 0x00, 18, 3, },
	[45] = { 0x00, 21, 3, },
	[46] = { 0x10, 0, 3, },
	[47] = { 0x10, 9, 3, },
	[48] = { 0x10, 3, 3, },
	[49] = { 0x10, 12, 3, },
	[50] = { 0x10, 6, 3, },
	[51] = { 0x10, 15, 3, },
	[52] = { 0x00, 21, 3, },
	[53] = { 0x00, 24, 3, },
	[54] = { 0x00, 6, 3, },
	[55] = { 0x00, 3, 3, },
	[56] = { 0x00, 15, 3, },
	[57] = { 0x00, 18, 3, },
	[58] = { 0x00, 9, 3, },
	[59] = { 0x00, 12, 3, },
	[60] = { 0x10, 24, 3, },
	[61] = { 0x10, 0, 3, },
	[62] = { 0x00, 27, 3, },
	[63] = { 0x10, 12, 3, },
	[64] = { 0x00, 0, 3, },
	[65] = { 0x10, 3, 3, },
	[66] = { 0x10, 27, 3, },
	[67] = { 0x10, 21, 3, },
	[68] = { 0x10, 21, 3, },
	[69] = { 0x10, 21, 3, },
	[70] = { 0x10, 18, 3, },
	[71] = { 0x10, 18, 3, },
	[72] = { 0x10, 21, 3, },
	[73] = { 0x10, 18, 3, },
	[74] = { 0x10, 18, 3, },
	[75] = { 0x00, 6, 3, },
	[76] = { 0x00, 9, 3, },
	[77] = { 0x00, 12, 3, },
	[78] = { 0x00, 15, 3, },
	[79] = { 0x00, 0, 3, },
	[80] = { 0x00, 3, 3, },
	[81] = { 0x00, 18, 3, },
	[82] = { 0x00, 21, 3, },
	[83] = { 0x00, 27, 3, },
	[84] = { 0x00, 24, 3, },
	[85] = { 0x10, 0, 3, },
	[86] = { 0x10, 3, 3, },
	[87] = { 0x10, 9, 3, },
	[88] = { 0x10, 6, 3, },
	[89] = { 0x00, 12, 3, },
	[90] = { 0x00, 12, 3, },
	[91] = { 0x00, 15, 3, },
	[92] = { 0x00, 15, 3, },
	[93] = { 0x00, 15, 3, },
	[94] = { 0x00, 12, 3, },
	[95] = { 0x00, 0, 3, },
	[96] = { 0x00, 6, 3, },
	[97] = { 0x00, 3, 3, },
	[98] = { 0x00, 9, 3, },
	[99] = { 0x00, 18, 3, },
	[100] = { 0x00, 27, 3, },
	[101] = { 0x00, 21, 3, },
	[102] = { 0x10, 0, 3, },
	[103] = { 0x00, 12, 3, },
	[104] = { 0x00, 24, 3, },
	[105] = { 0x10, 3, 3, },
	[106] = { 0x00, 0, 3, },
	[107] = { 0x00, 3, 3, },
	[108] = { 0x00, 9, 3, },
	[109] = { 0x00, 6, 3, },
	[110] = { 0x00, 12, 3, },
	[111] = { 0x00, 15, 3, },
	[112] = { 0x00, 21, 3, },
	[113] = { 0x00, 18, 3, },
	[114] = { 0x00, 24, 3, },
	[115] = { 0x00, 27, 3, },
	[116] = { 0x10, 3, 3, },
	[117] = { 0x10, 0, 3, },
	[118] = { 0x00, 18, 3, },
	[119] = { 0x00, 21, 3, },
	[120] = { 0x00, 27, 3, },
	[121] = { 0x00, 24, 3, },
	[122] = { 0x00, 9, 3, },
	[123] = { 0x00, 12, 3, },
	[124] = { 0x00, 15, 3, },
	[125] = { 0x00, 0, 3, },
	[126] = { 0x00, 3, 3, },
	[127] = { 0x00, 6, 3, },
	[128] = { 0x00, 9, 3, },
	[129] = { 0x00, 12, 3, },
	[130] = { 0x00, 15, 3, },
	[131] = { 0x00, 27, 3, },
	[132] = { 0x10, 3, 3, },
	[133] = { 0x10, 0, 3, },
	[134] = { 0x00, 18, 3, },
	[135] = { 0x00, 24, 3, },
	[136] = { 0x00, 21, 3, },
	[137] = { 0x00, 6, 3, },
	[138] = { 0x00, 9, 3, },
	[139] = { 0x00, 12, 3, },
	[140] = { 0x00, 15, 3, },
	[141] = { 0x00, 18, 3, },
	[142] = { 0x00, 21, 3, },
	[143] = { 0x00, 24, 3, },
	[144] = { 0x00, 27, 3, },
	[145] = { 0x10, 0, 3, },
	[146] = { 0x10, 0, 3, },
	[147] = { 0x00, 0, 3, },
	[148] = { 0x00, 3, 3, },
	[149] = { 0x10, 3, 3, },
	[150] = { 0x10, 3, 3, },
	[151] = { 0x10, 3, 3, },
	[152] = { 0x10, 3, 3, },
	[153] = { 0x10, 12, 3, },
	[154] = { 0x10, 9, 3, },
	[155] = { 0x10, 6, 3, },
	[156] = { 0x10, 6, 3, },
	[157] = { 0x10, 0, 3, },
	[158] = { 0x10, 0, 3, },
	[159] = { 0x10, 0, 3, },
	[160] = { 0x00, 3, 3, },
	[161] = { 0x00, 6, 3, },
	[162] = { 0x00, 6, 3, },
	[163] = { 0x00, 6, 3, },
	[164] = { 0x00, 18, 3, },
	[165] = { 0x00, 24, 3, },
	[166] = { 0x00, 21, 3, },
	[167] = { 0x00, 27, 3, },
	[168] = { 0x10, 0, 3, },
	[169] = { 0x10, 3, 3, },
	[170] = { 0x10, 9, 3, },
	[171] = { 0x10, 6, 3, },
	[172] = { 0x00, 9, 3, },
	[173] = { 0x00, 9, 3, },
	[174] = { 0x00, 27, 3, },
	[175] = { 0x00, 27, 3, },
	[176] = { 0x10, 0, 3, },
	[177] = { 0x10, 3, 3, },
	[178] = { 0x00, 24, 3, },
	[179] = { 0x00, 24, 3, },
	[180] = { 0x00, 0, 3, },
	[181] = { 0x00, 3, 3, },
	[182] = { 0x00, 6, 3, },
	[183] = { 0x00, 9, 3, },
	[184] = { 0x00, 12, 3, },
	[185] = { 0x00, 15, 3, },
	[186] = { 0x10, 12, 3, },
	[187] = { 0x10, 12, 3, },
	[188] = { 0x00, 12, 3, },
	[189] = { 0x00, 27, 3, },
	[190] = { 0x00, 15, 3, },
	[191] = { 0x10, 0, 3, },
	[192] = { 0x00, 0, 3, },
	[193] = { 0x10, 15, 3, },
	[194] = { 0x00, 18, 3, },
	[195] = { 0x10, 3, 3, },
	[196] = { 0x00, 3, 3, },
	[197] = { 0x10, 18, 3, },
	[198] = { 0x00, 21, 3, },
	[199] = { 0x10, 6, 3, },
	[200] = { 0x10, 27, 3, },
	[201] = { 0x20, 6, 3, },
	[202] = { 0x00, 24, 3, },
	[203] = { 0x10, 9, 3, },
	[204] = { 0x00, 6, 3, },
	[205] = { 0x00, 9, 3, },
	[206] = { 0x10, 24, 3, },
	[207] = { 0x10, 21, 3, },
	[208] = { 0x10, 21, 3, },
	[209] = { 0x10, 21, 3, },
	[210] = { 0x00, 0, 3, },
	[211] = { 0x00, 3, 3, },
	[212] = { 0x00, 6, 3, },
	[213] = { 0x00, 9, 3, },
	[214] = { 0x20, 0, 3, },
	[215] = { 0x20, 3, 3, },
	[216] = { 0x10, 6, 3, },
	[217] = { 0x10, 6, 3, },
	[218] = { 0x00, 15, 3, },
	[219] = { 0x00, 12, 3, },
	[220] = { 0x20, 3, 3, },
	[221] = { 0x20, 6, 3, },
	[222] = { 0x20, 12, 3, },
	[223] = { 0x20, 9, 3, },
	[224] = { 0x00, 18, 3, },
	[225] = { 0x00, 21, 3, },
	[226] = { 0x00, 24, 3, },
	[227] = { 0x00, 27, 3, },
	[228] = { 0x10, 0, 3, },
	[229] = { 0x10, 3, 3, },
	[230] = { 0x00, 0, 3, },
	[231] = { 0x00, 0, 3, },
	[232] = { 0x00, 0, 3, },
	[233] = { 0x00, 3, 3, },
	[234] = { 0x00, 3, 3, },
	[235] = { 0x00, 3, 3, },
	[236] = { 0x00, 3, 3, },
	[237] = { 0x00, 6, 3, },
	[238] = { 0x00, 6, 3, },
	[239] = { 0x00, 6, 3, },
	[240] = { 0x00, 6, 3, },
	[241] = { 0x00, 9, 3, },
	[242] = { 0x00, 9, 3, },
	[243] = { 0x00, 9, 3, },
	[244] = { 0x00, 9, 3, },
	[245] = { 0x00, 12, 3, },
	[246] = { 0x00, 15, 3, },
	[247] = { 0x00, 15, 3, },
	[248] = { 0x00, 12, 3, },
	[249] = { 0x00, 12, 3, },
	[250] = { 0x00, 12, 3, },
	[251] = { 0x00, 9, 3, },
	[252] = { 0x00, 12, 3, },
	[253] = { 0x00, 12, 3, },
	[254] = { 0x00, 12, 3, },
	[255] = { 0x00, 12, 3, },
	[256] = { 0x00, 15, 3, },
	[257] = { 0x00, 15, 3, },
	[258] = { 0x00, 15, 3, },
	[259] = { 0x10, 9, 3, },
	[260] = { 0x10, 12, 3, },
	[261] = { 0x10, 15, 3, },
	[262] = { 0x10, 18, 3, },
	[263] = { 0x10, 21, 3, },
	[264] = { 0x10, 24, 3, },
	[265] = { 0x10, 27, 3, },
	[266] = { 0x20, 0, 3, },
	[267] = { 0x00, 24, 3, },
	[268] = { 0x00, 27, 3, },
	[269] = { 0x00, 18, 3, },
	[270] = { 0x00, 21, 3, },
};
_Static_assert(ARRAY_SIZE(gpio_driving_info) == GPIO_NUM,
	       "gpio_driving_info array size not match");

static const struct gpio_drv_info gpio_driving_adv_info[] = {
	[46] = { 0x30, 0, 3, },
	[47] = { 0x30, 9, 3, },
	[48] = { 0x30, 3, 3, },
	[49] = { 0x30, 12, 3, },
	[50] = { 0x30, 6, 3, },
	[51] = { 0x30, 15, 3, },
	[52] = { 0x30, 0, 3, },
	[53] = { 0x30, 3, 3, },
	[75] = { 0x20, 0, 5, },
	[76] = { 0x20, 5, 5, },
	[77] = { 0x20, 10, 5, },
	[78] = { 0x20, 15, 5, },
	[99] = { 0x20, 0, 3, },
	[100] = { 0x20, 9, 3, },
	[101] = { 0x20, 3, 3, },
	[102] = { 0x20, 12, 3, },
	[104] = { 0x20, 6, 3, },
	[105] = { 0x20, 15, 3, },
	[123] = { 0x20, 0, 3, },
	[124] = { 0x20, 3, 3, },
	[164] = { 0x20, 0, 3, },
	[165] = { 0x20, 6, 3, },
	[166] = { 0x20, 3, 3, },
	[167] = { 0x20, 9, 3, },
	[168] = { 0x20, 12, 3, },
	[170] = { 0x20, 15, 3, },
	[176] = { 0x20, 0, 3, },
	[177] = { 0x20, 3, 3, },
	[188] = { 0x40, 0, 3, },
	[189] = { 0x40, 15, 3, },
	[190] = { 0x40, 3, 3, },
	[191] = { 0x40, 18, 3, },
	[194] = { 0x40, 6, 3, },
	[195] = { 0x40, 21, 3, },
	[198] = { 0x40, 9, 3, },
	[199] = { 0x40, 24, 3, },
	[200] = { 0x50, 0, 3, },
	[201] = { 0x50, 9, 3, },
	[202] = { 0x40, 12, 3, },
	[203] = { 0x40, 27, 3, },
	[214] = { 0x50, 3, 3, },
	[215] = { 0x50, 6, 3, },
};

void *gpio_find_reg_addr(gpio_t gpio)
{
	void *reg_addr;

	switch (gpio.base & 0x0f) {
	case 1:
		reg_addr = (void *)IOCFG_RT_BASE;
		break;
	case 2:
		reg_addr = (void *)IOCFG_RM1_BASE;
		break;
	case 3:
		reg_addr = (void *)IOCFG_RM2_BASE;
		break;
	case 4:
		reg_addr = (void *)IOCFG_RB_BASE;
		break;
	case 5:
		reg_addr = (void *)IOCFG_BM1_BASE;
		break;
	case 6:
		reg_addr = (void *)IOCFG_BM2_BASE;
		break;
	case 7:
		reg_addr = (void *)IOCFG_BM3_BASE;
		break;
	case 8:
		reg_addr = (void *)IOCFG_LT_BASE;
		break;
	case 9:
		reg_addr = (void *)IOCFG_LM1_BASE;
		break;
	case 10:
		reg_addr = (void *)IOCFG_LM2_BASE;
		break;
	case 11:
		reg_addr = (void *)IOCFG_LB1_BASE;
		break;
	case 12:
		reg_addr = (void *)IOCFG_LB2_BASE;
		break;
	case 13:
		reg_addr = (void *)IOCFG_TM1_BASE;
		break;
	case 14:
		reg_addr = (void *)IOCFG_TM2_BASE;
		break;
	case 15:
		reg_addr = (void *)IOCFG_TM3_BASE;
		break;
	default:
		reg_addr = NULL;
		break;
	}

	return reg_addr;
}

const struct gpio_drv_info *get_gpio_driving_info(uint32_t raw_id)
{
	if (raw_id >= ARRAY_SIZE(gpio_driving_info))
		return NULL;
	return &gpio_driving_info[raw_id];
}

const struct gpio_drv_info *get_gpio_driving_adv_info(uint32_t raw_id)
{
	if (raw_id >= ARRAY_SIZE(gpio_driving_adv_info))
		return NULL;
	return &gpio_driving_adv_info[raw_id];
}