129f5a494SLorenzo Bianconi // SPDX-License-Identifier: ISC
229f5a494SLorenzo Bianconi /* Copyright (C) 2023 MediaTek Inc. */
329f5a494SLorenzo Bianconi 
429f5a494SLorenzo Bianconi #include <linux/acpi.h>
529f5a494SLorenzo Bianconi #include "mt792x.h"
629f5a494SLorenzo Bianconi 
729f5a494SLorenzo Bianconi static int
mt792x_acpi_read(struct mt792x_dev * dev,u8 * method,u8 ** tbl,u32 * len)829f5a494SLorenzo Bianconi mt792x_acpi_read(struct mt792x_dev *dev, u8 *method, u8 **tbl, u32 *len)
929f5a494SLorenzo Bianconi {
1029f5a494SLorenzo Bianconi 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
1129f5a494SLorenzo Bianconi 	struct mt76_dev *mdev = &dev->mt76;
1229f5a494SLorenzo Bianconi 	union acpi_object *sar_root;
1329f5a494SLorenzo Bianconi 	acpi_handle root, handle;
1429f5a494SLorenzo Bianconi 	acpi_status status;
1529f5a494SLorenzo Bianconi 	u32 i = 0;
1629f5a494SLorenzo Bianconi 	int ret;
1729f5a494SLorenzo Bianconi 
1829f5a494SLorenzo Bianconi 	root = ACPI_HANDLE(mdev->dev);
1929f5a494SLorenzo Bianconi 	if (!root)
2029f5a494SLorenzo Bianconi 		return -EOPNOTSUPP;
2129f5a494SLorenzo Bianconi 
2229f5a494SLorenzo Bianconi 	status = acpi_get_handle(root, method, &handle);
2329f5a494SLorenzo Bianconi 	if (ACPI_FAILURE(status))
2429f5a494SLorenzo Bianconi 		return -EIO;
2529f5a494SLorenzo Bianconi 
2629f5a494SLorenzo Bianconi 	status = acpi_evaluate_object(handle, NULL, NULL, &buf);
2729f5a494SLorenzo Bianconi 	if (ACPI_FAILURE(status))
2829f5a494SLorenzo Bianconi 		return -EIO;
2929f5a494SLorenzo Bianconi 
3029f5a494SLorenzo Bianconi 	sar_root = buf.pointer;
3129f5a494SLorenzo Bianconi 	if (sar_root->type != ACPI_TYPE_PACKAGE ||
3229f5a494SLorenzo Bianconi 	    sar_root->package.count < 4 ||
3329f5a494SLorenzo Bianconi 	    sar_root->package.elements[0].type != ACPI_TYPE_INTEGER) {
3429f5a494SLorenzo Bianconi 		dev_err(mdev->dev, "sar cnt = %d\n",
3529f5a494SLorenzo Bianconi 			sar_root->package.count);
3629f5a494SLorenzo Bianconi 		ret = -EINVAL;
3729f5a494SLorenzo Bianconi 		goto free;
3829f5a494SLorenzo Bianconi 	}
3929f5a494SLorenzo Bianconi 
4029f5a494SLorenzo Bianconi 	if (!*tbl) {
4129f5a494SLorenzo Bianconi 		*tbl = devm_kzalloc(mdev->dev, sar_root->package.count,
4229f5a494SLorenzo Bianconi 				    GFP_KERNEL);
4329f5a494SLorenzo Bianconi 		if (!*tbl) {
4429f5a494SLorenzo Bianconi 			ret = -ENOMEM;
4529f5a494SLorenzo Bianconi 			goto free;
4629f5a494SLorenzo Bianconi 		}
4729f5a494SLorenzo Bianconi 	}
4829f5a494SLorenzo Bianconi 
4929f5a494SLorenzo Bianconi 	if (len)
5029f5a494SLorenzo Bianconi 		*len = sar_root->package.count;
5129f5a494SLorenzo Bianconi 
5229f5a494SLorenzo Bianconi 	for (i = 0; i < sar_root->package.count; i++) {
5329f5a494SLorenzo Bianconi 		union acpi_object *sar_unit = &sar_root->package.elements[i];
5429f5a494SLorenzo Bianconi 
5529f5a494SLorenzo Bianconi 		if (sar_unit->type != ACPI_TYPE_INTEGER)
5629f5a494SLorenzo Bianconi 			break;
5729f5a494SLorenzo Bianconi 
5829f5a494SLorenzo Bianconi 		*(*tbl + i) = (u8)sar_unit->integer.value;
5929f5a494SLorenzo Bianconi 	}
6029f5a494SLorenzo Bianconi 
6129f5a494SLorenzo Bianconi 	ret = i == sar_root->package.count ? 0 : -EINVAL;
6229f5a494SLorenzo Bianconi free:
6329f5a494SLorenzo Bianconi 	kfree(sar_root);
6429f5a494SLorenzo Bianconi 
6529f5a494SLorenzo Bianconi 	return ret;
6629f5a494SLorenzo Bianconi }
6729f5a494SLorenzo Bianconi 
6829f5a494SLorenzo Bianconi /* MTCL : Country List Table for 6G band */
69*9d5d48d9SMing Yen Hsieh static int
mt792x_asar_acpi_read_mtcl(struct mt792x_dev * dev,u8 ** table,u8 * version)7029f5a494SLorenzo Bianconi mt792x_asar_acpi_read_mtcl(struct mt792x_dev *dev, u8 **table, u8 *version)
7129f5a494SLorenzo Bianconi {
72*9d5d48d9SMing Yen Hsieh 	int ret;
73*9d5d48d9SMing Yen Hsieh 
74*9d5d48d9SMing Yen Hsieh 	*version = ((ret = mt792x_acpi_read(dev, MT792x_ACPI_MTCL, table, NULL)) < 0)
75*9d5d48d9SMing Yen Hsieh 		   ? 1 : 2;
76*9d5d48d9SMing Yen Hsieh 
77*9d5d48d9SMing Yen Hsieh 	return ret;
7829f5a494SLorenzo Bianconi }
7929f5a494SLorenzo Bianconi 
8029f5a494SLorenzo Bianconi /* MTDS : Dynamic SAR Power Table */
8129f5a494SLorenzo Bianconi static int
mt792x_asar_acpi_read_mtds(struct mt792x_dev * dev,u8 ** table,u8 version)8229f5a494SLorenzo Bianconi mt792x_asar_acpi_read_mtds(struct mt792x_dev *dev, u8 **table, u8 version)
8329f5a494SLorenzo Bianconi {
8429f5a494SLorenzo Bianconi 	int len, ret, sarlen, prelen, tblcnt;
8529f5a494SLorenzo Bianconi 	bool enable;
8629f5a494SLorenzo Bianconi 
8729f5a494SLorenzo Bianconi 	ret = mt792x_acpi_read(dev, MT792x_ACPI_MTDS, table, &len);
8829f5a494SLorenzo Bianconi 	if (ret)
8929f5a494SLorenzo Bianconi 		return ret;
9029f5a494SLorenzo Bianconi 
9129f5a494SLorenzo Bianconi 	/* Table content validation */
9229f5a494SLorenzo Bianconi 	switch (version) {
9329f5a494SLorenzo Bianconi 	case 1:
9429f5a494SLorenzo Bianconi 		enable = ((struct mt792x_asar_dyn *)*table)->enable;
9529f5a494SLorenzo Bianconi 		sarlen = sizeof(struct mt792x_asar_dyn_limit);
9629f5a494SLorenzo Bianconi 		prelen = sizeof(struct mt792x_asar_dyn);
9729f5a494SLorenzo Bianconi 		break;
9829f5a494SLorenzo Bianconi 	case 2:
9929f5a494SLorenzo Bianconi 		enable = ((struct mt792x_asar_dyn_v2 *)*table)->enable;
10029f5a494SLorenzo Bianconi 		sarlen = sizeof(struct mt792x_asar_dyn_limit_v2);
10129f5a494SLorenzo Bianconi 		prelen = sizeof(struct mt792x_asar_dyn_v2);
10229f5a494SLorenzo Bianconi 		break;
10329f5a494SLorenzo Bianconi 	default:
10429f5a494SLorenzo Bianconi 		return -EINVAL;
10529f5a494SLorenzo Bianconi 	}
10629f5a494SLorenzo Bianconi 
10729f5a494SLorenzo Bianconi 	tblcnt = (len - prelen) / sarlen;
10829f5a494SLorenzo Bianconi 	if (!enable ||
10929f5a494SLorenzo Bianconi 	    tblcnt > MT792x_ASAR_MAX_DYN || tblcnt < MT792x_ASAR_MIN_DYN)
11029f5a494SLorenzo Bianconi 		return -EINVAL;
11129f5a494SLorenzo Bianconi 
11229f5a494SLorenzo Bianconi 	return 0;
11329f5a494SLorenzo Bianconi }
11429f5a494SLorenzo Bianconi 
11529f5a494SLorenzo Bianconi /* MTGS : Geo SAR Power Table */
11629f5a494SLorenzo Bianconi static int
mt792x_asar_acpi_read_mtgs(struct mt792x_dev * dev,u8 ** table,u8 version)11729f5a494SLorenzo Bianconi mt792x_asar_acpi_read_mtgs(struct mt792x_dev *dev, u8 **table, u8 version)
11829f5a494SLorenzo Bianconi {
11929f5a494SLorenzo Bianconi 	int len, ret, sarlen, prelen, tblcnt;
12029f5a494SLorenzo Bianconi 
12129f5a494SLorenzo Bianconi 	ret = mt792x_acpi_read(dev, MT792x_ACPI_MTGS, table, &len);
12229f5a494SLorenzo Bianconi 	if (ret)
12329f5a494SLorenzo Bianconi 		return ret;
12429f5a494SLorenzo Bianconi 
12529f5a494SLorenzo Bianconi 	/* Table content validation */
12629f5a494SLorenzo Bianconi 	switch (version) {
12729f5a494SLorenzo Bianconi 	case 1:
12829f5a494SLorenzo Bianconi 		sarlen = sizeof(struct mt792x_asar_geo_limit);
12929f5a494SLorenzo Bianconi 		prelen = sizeof(struct mt792x_asar_geo);
13029f5a494SLorenzo Bianconi 		break;
13129f5a494SLorenzo Bianconi 	case 2:
13229f5a494SLorenzo Bianconi 		sarlen = sizeof(struct mt792x_asar_geo_limit_v2);
13329f5a494SLorenzo Bianconi 		prelen = sizeof(struct mt792x_asar_geo_v2);
13429f5a494SLorenzo Bianconi 		break;
13529f5a494SLorenzo Bianconi 	default:
13629f5a494SLorenzo Bianconi 		return -EINVAL;
13729f5a494SLorenzo Bianconi 	}
13829f5a494SLorenzo Bianconi 
13929f5a494SLorenzo Bianconi 	tblcnt = (len - prelen) / sarlen;
14029f5a494SLorenzo Bianconi 	if (tblcnt > MT792x_ASAR_MAX_GEO || tblcnt < MT792x_ASAR_MIN_GEO)
14129f5a494SLorenzo Bianconi 		return -EINVAL;
14229f5a494SLorenzo Bianconi 
14329f5a494SLorenzo Bianconi 	return 0;
14429f5a494SLorenzo Bianconi }
14529f5a494SLorenzo Bianconi 
14629f5a494SLorenzo Bianconi /* MTFG : Flag Table */
14729f5a494SLorenzo Bianconi static int
mt792x_asar_acpi_read_mtfg(struct mt792x_dev * dev,u8 ** table)14829f5a494SLorenzo Bianconi mt792x_asar_acpi_read_mtfg(struct mt792x_dev *dev, u8 **table)
14929f5a494SLorenzo Bianconi {
15029f5a494SLorenzo Bianconi 	int len, ret;
15129f5a494SLorenzo Bianconi 
15229f5a494SLorenzo Bianconi 	ret = mt792x_acpi_read(dev, MT792x_ACPI_MTFG, table, &len);
15329f5a494SLorenzo Bianconi 	if (ret)
15429f5a494SLorenzo Bianconi 		return ret;
15529f5a494SLorenzo Bianconi 
15629f5a494SLorenzo Bianconi 	if (len < MT792x_ASAR_MIN_FG)
15729f5a494SLorenzo Bianconi 		return -EINVAL;
15829f5a494SLorenzo Bianconi 
15929f5a494SLorenzo Bianconi 	return 0;
16029f5a494SLorenzo Bianconi }
16129f5a494SLorenzo Bianconi 
mt792x_init_acpi_sar(struct mt792x_dev * dev)16229f5a494SLorenzo Bianconi int mt792x_init_acpi_sar(struct mt792x_dev *dev)
16329f5a494SLorenzo Bianconi {
16429f5a494SLorenzo Bianconi 	struct mt792x_acpi_sar *asar;
16529f5a494SLorenzo Bianconi 	int ret;
16629f5a494SLorenzo Bianconi 
16729f5a494SLorenzo Bianconi 	asar = devm_kzalloc(dev->mt76.dev, sizeof(*asar), GFP_KERNEL);
16829f5a494SLorenzo Bianconi 	if (!asar)
16929f5a494SLorenzo Bianconi 		return -ENOMEM;
17029f5a494SLorenzo Bianconi 
171*9d5d48d9SMing Yen Hsieh 	ret = mt792x_asar_acpi_read_mtcl(dev, (u8 **)&asar->countrylist, &asar->ver);
172*9d5d48d9SMing Yen Hsieh 	if (ret) {
173*9d5d48d9SMing Yen Hsieh 		devm_kfree(dev->mt76.dev, asar->countrylist);
174*9d5d48d9SMing Yen Hsieh 		asar->countrylist = NULL;
175*9d5d48d9SMing Yen Hsieh 	}
17629f5a494SLorenzo Bianconi 
17729f5a494SLorenzo Bianconi 	ret = mt792x_asar_acpi_read_mtds(dev, (u8 **)&asar->dyn, asar->ver);
17829f5a494SLorenzo Bianconi 	if (ret) {
17929f5a494SLorenzo Bianconi 		devm_kfree(dev->mt76.dev, asar->dyn);
180*9d5d48d9SMing Yen Hsieh 		asar->dyn = NULL;
18129f5a494SLorenzo Bianconi 	}
18229f5a494SLorenzo Bianconi 
18329f5a494SLorenzo Bianconi 	/* MTGS is optional */
18429f5a494SLorenzo Bianconi 	ret = mt792x_asar_acpi_read_mtgs(dev, (u8 **)&asar->geo, asar->ver);
18529f5a494SLorenzo Bianconi 	if (ret) {
18629f5a494SLorenzo Bianconi 		devm_kfree(dev->mt76.dev, asar->geo);
18729f5a494SLorenzo Bianconi 		asar->geo = NULL;
18829f5a494SLorenzo Bianconi 	}
18929f5a494SLorenzo Bianconi 
19029f5a494SLorenzo Bianconi 	/* MTFG is optional */
19129f5a494SLorenzo Bianconi 	ret = mt792x_asar_acpi_read_mtfg(dev, (u8 **)&asar->fg);
19229f5a494SLorenzo Bianconi 	if (ret) {
19329f5a494SLorenzo Bianconi 		devm_kfree(dev->mt76.dev, asar->fg);
19429f5a494SLorenzo Bianconi 		asar->fg = NULL;
19529f5a494SLorenzo Bianconi 	}
19629f5a494SLorenzo Bianconi 	dev->phy.acpisar = asar;
19729f5a494SLorenzo Bianconi 
19829f5a494SLorenzo Bianconi 	return 0;
19929f5a494SLorenzo Bianconi }
20029f5a494SLorenzo Bianconi EXPORT_SYMBOL_GPL(mt792x_init_acpi_sar);
20129f5a494SLorenzo Bianconi 
20229f5a494SLorenzo Bianconi static s8
mt792x_asar_get_geo_pwr(struct mt792x_phy * phy,enum nl80211_band band,s8 dyn_power)20329f5a494SLorenzo Bianconi mt792x_asar_get_geo_pwr(struct mt792x_phy *phy,
20429f5a494SLorenzo Bianconi 			enum nl80211_band band, s8 dyn_power)
20529f5a494SLorenzo Bianconi {
20629f5a494SLorenzo Bianconi 	struct mt792x_acpi_sar *asar = phy->acpisar;
20729f5a494SLorenzo Bianconi 	struct mt792x_asar_geo_band *band_pwr;
20829f5a494SLorenzo Bianconi 	s8 geo_power;
20929f5a494SLorenzo Bianconi 	u8 idx, max;
21029f5a494SLorenzo Bianconi 
21129f5a494SLorenzo Bianconi 	if (!asar->geo)
21229f5a494SLorenzo Bianconi 		return dyn_power;
21329f5a494SLorenzo Bianconi 
21429f5a494SLorenzo Bianconi 	switch (phy->mt76->dev->region) {
21529f5a494SLorenzo Bianconi 	case NL80211_DFS_FCC:
21629f5a494SLorenzo Bianconi 		idx = 0;
21729f5a494SLorenzo Bianconi 		break;
21829f5a494SLorenzo Bianconi 	case NL80211_DFS_ETSI:
21929f5a494SLorenzo Bianconi 		idx = 1;
22029f5a494SLorenzo Bianconi 		break;
22129f5a494SLorenzo Bianconi 	default: /* WW */
22229f5a494SLorenzo Bianconi 		idx = 2;
22329f5a494SLorenzo Bianconi 		break;
22429f5a494SLorenzo Bianconi 	}
22529f5a494SLorenzo Bianconi 
22629f5a494SLorenzo Bianconi 	if (asar->ver == 1) {
22729f5a494SLorenzo Bianconi 		band_pwr = &asar->geo->tbl[idx].band[0];
22829f5a494SLorenzo Bianconi 		max = ARRAY_SIZE(asar->geo->tbl[idx].band);
22929f5a494SLorenzo Bianconi 	} else {
23029f5a494SLorenzo Bianconi 		band_pwr = &asar->geo_v2->tbl[idx].band[0];
23129f5a494SLorenzo Bianconi 		max = ARRAY_SIZE(asar->geo_v2->tbl[idx].band);
23229f5a494SLorenzo Bianconi 	}
23329f5a494SLorenzo Bianconi 
23429f5a494SLorenzo Bianconi 	switch (band) {
23529f5a494SLorenzo Bianconi 	case NL80211_BAND_2GHZ:
23629f5a494SLorenzo Bianconi 		idx = 0;
23729f5a494SLorenzo Bianconi 		break;
23829f5a494SLorenzo Bianconi 	case NL80211_BAND_5GHZ:
23929f5a494SLorenzo Bianconi 		idx = 1;
24029f5a494SLorenzo Bianconi 		break;
24129f5a494SLorenzo Bianconi 	case NL80211_BAND_6GHZ:
24229f5a494SLorenzo Bianconi 		idx = 2;
24329f5a494SLorenzo Bianconi 		break;
24429f5a494SLorenzo Bianconi 	default:
24529f5a494SLorenzo Bianconi 		return dyn_power;
24629f5a494SLorenzo Bianconi 	}
24729f5a494SLorenzo Bianconi 
24829f5a494SLorenzo Bianconi 	if (idx >= max)
24929f5a494SLorenzo Bianconi 		return dyn_power;
25029f5a494SLorenzo Bianconi 
25129f5a494SLorenzo Bianconi 	geo_power = (band_pwr + idx)->pwr;
25229f5a494SLorenzo Bianconi 	dyn_power += (band_pwr + idx)->offset;
25329f5a494SLorenzo Bianconi 
25429f5a494SLorenzo Bianconi 	return min(geo_power, dyn_power);
25529f5a494SLorenzo Bianconi }
25629f5a494SLorenzo Bianconi 
25729f5a494SLorenzo Bianconi static s8
mt792x_asar_range_pwr(struct mt792x_phy * phy,const struct cfg80211_sar_freq_ranges * range,u8 idx)25829f5a494SLorenzo Bianconi mt792x_asar_range_pwr(struct mt792x_phy *phy,
25929f5a494SLorenzo Bianconi 		      const struct cfg80211_sar_freq_ranges *range,
26029f5a494SLorenzo Bianconi 		      u8 idx)
26129f5a494SLorenzo Bianconi {
26229f5a494SLorenzo Bianconi 	const struct cfg80211_sar_capa *capa = phy->mt76->hw->wiphy->sar_capa;
26329f5a494SLorenzo Bianconi 	struct mt792x_acpi_sar *asar = phy->acpisar;
26429f5a494SLorenzo Bianconi 	u8 *limit, band, max;
26529f5a494SLorenzo Bianconi 
26629f5a494SLorenzo Bianconi 	if (!capa)
26729f5a494SLorenzo Bianconi 		return 127;
26829f5a494SLorenzo Bianconi 
26929f5a494SLorenzo Bianconi 	if (asar->ver == 1) {
27029f5a494SLorenzo Bianconi 		limit = &asar->dyn->tbl[0].frp[0];
27129f5a494SLorenzo Bianconi 		max = ARRAY_SIZE(asar->dyn->tbl[0].frp);
27229f5a494SLorenzo Bianconi 	} else {
27329f5a494SLorenzo Bianconi 		limit = &asar->dyn_v2->tbl[0].frp[0];
27429f5a494SLorenzo Bianconi 		max = ARRAY_SIZE(asar->dyn_v2->tbl[0].frp);
27529f5a494SLorenzo Bianconi 	}
27629f5a494SLorenzo Bianconi 
27729f5a494SLorenzo Bianconi 	if (idx >= max)
27829f5a494SLorenzo Bianconi 		return 127;
27929f5a494SLorenzo Bianconi 
28029f5a494SLorenzo Bianconi 	if (range->start_freq >= 5945)
28129f5a494SLorenzo Bianconi 		band = NL80211_BAND_6GHZ;
28229f5a494SLorenzo Bianconi 	else if (range->start_freq >= 5150)
28329f5a494SLorenzo Bianconi 		band = NL80211_BAND_5GHZ;
28429f5a494SLorenzo Bianconi 	else
28529f5a494SLorenzo Bianconi 		band = NL80211_BAND_2GHZ;
28629f5a494SLorenzo Bianconi 
28729f5a494SLorenzo Bianconi 	return mt792x_asar_get_geo_pwr(phy, band, limit[idx]);
28829f5a494SLorenzo Bianconi }
28929f5a494SLorenzo Bianconi 
mt792x_init_acpi_sar_power(struct mt792x_phy * phy,bool set_default)29029f5a494SLorenzo Bianconi int mt792x_init_acpi_sar_power(struct mt792x_phy *phy, bool set_default)
29129f5a494SLorenzo Bianconi {
29229f5a494SLorenzo Bianconi 	const struct cfg80211_sar_capa *capa = phy->mt76->hw->wiphy->sar_capa;
29329f5a494SLorenzo Bianconi 	int i;
29429f5a494SLorenzo Bianconi 
295*9d5d48d9SMing Yen Hsieh 	if (!phy->acpisar || !((struct mt792x_acpi_sar *)phy->acpisar)->dyn)
29629f5a494SLorenzo Bianconi 		return 0;
29729f5a494SLorenzo Bianconi 
29829f5a494SLorenzo Bianconi 	/* When ACPI SAR enabled in HW, we should apply rules for .frp
29929f5a494SLorenzo Bianconi 	 * 1. w/o .sar_specs : set ACPI SAR power as the defatul value
30029f5a494SLorenzo Bianconi 	 * 2. w/  .sar_specs : set power with min(.sar_specs, ACPI_SAR)
30129f5a494SLorenzo Bianconi 	 */
30229f5a494SLorenzo Bianconi 	for (i = 0; i < capa->num_freq_ranges; i++) {
30329f5a494SLorenzo Bianconi 		struct mt76_freq_range_power *frp = &phy->mt76->frp[i];
30429f5a494SLorenzo Bianconi 
30529f5a494SLorenzo Bianconi 		frp->range = set_default ? &capa->freq_ranges[i] : frp->range;
30629f5a494SLorenzo Bianconi 		if (!frp->range)
30729f5a494SLorenzo Bianconi 			continue;
30829f5a494SLorenzo Bianconi 
30929f5a494SLorenzo Bianconi 		frp->power = min_t(s8, set_default ? 127 : frp->power,
31029f5a494SLorenzo Bianconi 				   mt792x_asar_range_pwr(phy, frp->range, i));
31129f5a494SLorenzo Bianconi 	}
31229f5a494SLorenzo Bianconi 
31329f5a494SLorenzo Bianconi 	return 0;
31429f5a494SLorenzo Bianconi }
31529f5a494SLorenzo Bianconi EXPORT_SYMBOL_GPL(mt792x_init_acpi_sar_power);
31629f5a494SLorenzo Bianconi 
mt792x_acpi_get_flags(struct mt792x_phy * phy)31729f5a494SLorenzo Bianconi u8 mt792x_acpi_get_flags(struct mt792x_phy *phy)
31829f5a494SLorenzo Bianconi {
31929f5a494SLorenzo Bianconi 	struct mt792x_acpi_sar *acpisar = phy->acpisar;
32029f5a494SLorenzo Bianconi 	struct mt792x_asar_fg *fg;
32129f5a494SLorenzo Bianconi 	struct {
32229f5a494SLorenzo Bianconi 		u8 acpi_idx;
32329f5a494SLorenzo Bianconi 		u8 chip_idx;
32429f5a494SLorenzo Bianconi 	} map[] = {
32529f5a494SLorenzo Bianconi 		{ 1, 1 },
32629f5a494SLorenzo Bianconi 		{ 4, 2 },
32729f5a494SLorenzo Bianconi 	};
32829f5a494SLorenzo Bianconi 	u8 flags = BIT(0);
32929f5a494SLorenzo Bianconi 	int i, j;
33029f5a494SLorenzo Bianconi 
33129f5a494SLorenzo Bianconi 	if (!acpisar)
33229f5a494SLorenzo Bianconi 		return 0;
33329f5a494SLorenzo Bianconi 
33429f5a494SLorenzo Bianconi 	fg = acpisar->fg;
33529f5a494SLorenzo Bianconi 	if (!fg)
33629f5a494SLorenzo Bianconi 		return flags;
33729f5a494SLorenzo Bianconi 
33829f5a494SLorenzo Bianconi 	/* pickup necessary settings per device and
33929f5a494SLorenzo Bianconi 	 * translate the index of bitmap for chip command.
34029f5a494SLorenzo Bianconi 	 */
34129f5a494SLorenzo Bianconi 	for (i = 0; i < fg->nr_flag; i++) {
34229f5a494SLorenzo Bianconi 		for (j = 0; j < ARRAY_SIZE(map); j++) {
34329f5a494SLorenzo Bianconi 			if (fg->flag[i] == map[j].acpi_idx) {
34429f5a494SLorenzo Bianconi 				flags |= BIT(map[j].chip_idx);
34529f5a494SLorenzo Bianconi 				break;
34629f5a494SLorenzo Bianconi 			}
34729f5a494SLorenzo Bianconi 		}
34829f5a494SLorenzo Bianconi 	}
34929f5a494SLorenzo Bianconi 
35029f5a494SLorenzo Bianconi 	return flags;
35129f5a494SLorenzo Bianconi }
35229f5a494SLorenzo Bianconi EXPORT_SYMBOL_GPL(mt792x_acpi_get_flags);
353