drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
Extension
.c
Size
6081 bytes
Lines
262
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
 */

#include <linux/delay.h>

#include "mt76x2u.h"
#include "eeprom.h"
#include "../mt76x02_phy.h"
#include "../mt76x02_usb.h"

static void mt76x2u_init_dma(struct mt76x02_dev *dev)
{
	u32 val = mt76_rr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG));

	val |= MT_USB_DMA_CFG_RX_DROP_OR_PAD |
	       MT_USB_DMA_CFG_RX_BULK_EN |
	       MT_USB_DMA_CFG_TX_BULK_EN;

	/* disable AGGR_BULK_RX in order to receive one
	 * frame in each rx urb and avoid copies
	 */
	val &= ~MT_USB_DMA_CFG_RX_BULK_AGG_EN;
	mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);
}

static void mt76x2u_power_on_rf_patch(struct mt76x02_dev *dev)
{
	mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), BIT(0) | BIT(16));
	udelay(1);

	mt76_clear(dev, MT_VEND_ADDR(CFG, 0x1c), 0xff);
	mt76_set(dev, MT_VEND_ADDR(CFG, 0x1c), 0x30);

	mt76_wr(dev, MT_VEND_ADDR(CFG, 0x14), 0x484f);
	udelay(1);

	mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), BIT(17));
	usleep_range(150, 200);

	mt76_clear(dev, MT_VEND_ADDR(CFG, 0x130), BIT(16));
	usleep_range(50, 100);

	mt76_set(dev, MT_VEND_ADDR(CFG, 0x14c), BIT(19) | BIT(20));
}

static void mt76x2u_power_on_rf(struct mt76x02_dev *dev, int unit)
{
	int shift = unit ? 8 : 0;
	u32 val = (BIT(1) | BIT(3) | BIT(4) | BIT(5)) << shift;

	/* Enable RF BG */
	mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), BIT(0) << shift);
	usleep_range(10, 20);

	/* Enable RFDIG LDO/AFE/ABB/ADDA */
	mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), val);
	usleep_range(10, 20);

	/* Switch RFDIG power to internal LDO */
	mt76_clear(dev, MT_VEND_ADDR(CFG, 0x130), BIT(2) << shift);
	usleep_range(10, 20);

	mt76x2u_power_on_rf_patch(dev);

	mt76_set(dev, 0x530, 0xf);
}

static void mt76x2u_power_on(struct mt76x02_dev *dev)
{
	u32 val;

	/* Turn on WL MTCMOS */
	mt76_set(dev, MT_VEND_ADDR(CFG, 0x148),
		 MT_WLAN_MTC_CTRL_MTCMOS_PWR_UP);

	val = MT_WLAN_MTC_CTRL_STATE_UP |
	      MT_WLAN_MTC_CTRL_PWR_ACK |
	      MT_WLAN_MTC_CTRL_PWR_ACK_S;

	mt76_poll(dev, MT_VEND_ADDR(CFG, 0x148), val, val, 1000);

	mt76_clear(dev, MT_VEND_ADDR(CFG, 0x148), 0x7f << 16);
	usleep_range(10, 20);

	mt76_clear(dev, MT_VEND_ADDR(CFG, 0x148), 0xf << 24);
	usleep_range(10, 20);

	mt76_set(dev, MT_VEND_ADDR(CFG, 0x148), 0xf << 24);

Annotation

Implementation Notes