1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2019 MediaTek Inc.
4 * Author: Ryder Lee <ryder.lee@mediatek.com>
5 * Felix Fietkau <nbd@nbd.name>
11 static int mt7615_efuse_read(struct mt7615_dev
*dev
, u32 base
,
17 val
= mt76_rr(dev
, base
+ MT_EFUSE_CTRL
);
18 val
&= ~(MT_EFUSE_CTRL_AIN
| MT_EFUSE_CTRL_MODE
);
19 val
|= FIELD_PREP(MT_EFUSE_CTRL_AIN
, addr
& ~0xf);
20 val
|= MT_EFUSE_CTRL_KICK
;
21 mt76_wr(dev
, base
+ MT_EFUSE_CTRL
, val
);
23 if (!mt76_poll(dev
, base
+ MT_EFUSE_CTRL
, MT_EFUSE_CTRL_KICK
, 0, 1000))
28 val
= mt76_rr(dev
, base
+ MT_EFUSE_CTRL
);
29 if ((val
& MT_EFUSE_CTRL_AOUT
) == MT_EFUSE_CTRL_AOUT
||
30 WARN_ON_ONCE(!(val
& MT_EFUSE_CTRL_VALID
))) {
31 memset(data
, 0x0, 16);
35 for (i
= 0; i
< 4; i
++) {
36 val
= mt76_rr(dev
, base
+ MT_EFUSE_RDATA(i
));
37 put_unaligned_le32(val
, data
+ 4 * i
);
43 static int mt7615_efuse_init(struct mt7615_dev
*dev
)
45 u32 base
= mt7615_reg_map(dev
, MT_EFUSE_BASE
);
46 int len
= MT7615_EEPROM_SIZE
;
50 if (mt76_rr(dev
, base
+ MT_EFUSE_BASE_CTRL
) & MT_EFUSE_BASE_CTRL_EMPTY
)
53 dev
->mt76
.otp
.data
= devm_kzalloc(dev
->mt76
.dev
, len
, GFP_KERNEL
);
54 dev
->mt76
.otp
.size
= len
;
55 if (!dev
->mt76
.otp
.data
)
58 buf
= dev
->mt76
.otp
.data
;
59 for (i
= 0; i
+ 16 <= len
; i
+= 16) {
60 ret
= mt7615_efuse_read(dev
, base
, i
, buf
+ i
);
68 static int mt7615_eeprom_load(struct mt7615_dev
*dev
)
72 ret
= mt76_eeprom_init(&dev
->mt76
, MT7615_EEPROM_SIZE
);
76 return mt7615_efuse_init(dev
);
79 int mt7615_eeprom_init(struct mt7615_dev
*dev
)
83 ret
= mt7615_eeprom_load(dev
);
87 memcpy(dev
->mt76
.eeprom
.data
, dev
->mt76
.otp
.data
, MT7615_EEPROM_SIZE
);
89 dev
->mt76
.cap
.has_2ghz
= true;
90 dev
->mt76
.cap
.has_5ghz
= true;
92 memcpy(dev
->mt76
.macaddr
, dev
->mt76
.eeprom
.data
+ MT_EE_MAC_ADDR
,
95 mt76_eeprom_override(&dev
->mt76
);