162306a36Sopenharmony_ci// SPDX-License-Identifier: ISC
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#include <linux/kernel.h>
462306a36Sopenharmony_ci#include <linux/module.h>
562306a36Sopenharmony_ci#include <linux/pci.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include "mt7603.h"
862306a36Sopenharmony_ci
962306a36Sopenharmony_cistatic const struct pci_device_id mt76pci_device_table[] = {
1062306a36Sopenharmony_ci	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7603) },
1162306a36Sopenharmony_ci	{ },
1262306a36Sopenharmony_ci};
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cistatic int
1562306a36Sopenharmony_cimt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	struct mt7603_dev *dev;
1862306a36Sopenharmony_ci	struct mt76_dev *mdev;
1962306a36Sopenharmony_ci	int ret;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	ret = pcim_enable_device(pdev);
2262306a36Sopenharmony_ci	if (ret)
2362306a36Sopenharmony_ci		return ret;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
2662306a36Sopenharmony_ci	if (ret)
2762306a36Sopenharmony_ci		return ret;
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	pci_set_master(pdev);
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
3262306a36Sopenharmony_ci	if (ret)
3362306a36Sopenharmony_ci		return ret;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7603_ops,
3662306a36Sopenharmony_ci				 &mt7603_drv_ops);
3762306a36Sopenharmony_ci	if (!mdev)
3862306a36Sopenharmony_ci		return -ENOMEM;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	dev = container_of(mdev, struct mt7603_dev, mt76);
4162306a36Sopenharmony_ci	mt76_mmio_init(mdev, pcim_iomap_table(pdev)[0]);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
4462306a36Sopenharmony_ci		    (mt76_rr(dev, MT_HW_REV) & 0xff);
4562306a36Sopenharmony_ci	dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	mt76_wr(dev, MT_INT_MASK_CSR, 0);
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	ret = devm_request_irq(mdev->dev, pdev->irq, mt7603_irq_handler,
5062306a36Sopenharmony_ci			       IRQF_SHARED, KBUILD_MODNAME, dev);
5162306a36Sopenharmony_ci	if (ret)
5262306a36Sopenharmony_ci		goto error;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	ret = mt7603_register_device(dev);
5562306a36Sopenharmony_ci	if (ret)
5662306a36Sopenharmony_ci		goto error;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	return 0;
5962306a36Sopenharmony_cierror:
6062306a36Sopenharmony_ci	mt76_free_device(&dev->mt76);
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	return ret;
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistatic void
6662306a36Sopenharmony_cimt76pci_remove(struct pci_dev *pdev)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	struct mt76_dev *mdev = pci_get_drvdata(pdev);
6962306a36Sopenharmony_ci	struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	mt7603_unregister_device(dev);
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, mt76pci_device_table);
7562306a36Sopenharmony_ciMODULE_FIRMWARE(MT7603_FIRMWARE_E1);
7662306a36Sopenharmony_ciMODULE_FIRMWARE(MT7603_FIRMWARE_E2);
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistruct pci_driver mt7603_pci_driver = {
7962306a36Sopenharmony_ci	.name		= KBUILD_MODNAME,
8062306a36Sopenharmony_ci	.id_table	= mt76pci_device_table,
8162306a36Sopenharmony_ci	.probe		= mt76pci_probe,
8262306a36Sopenharmony_ci	.remove		= mt76pci_remove,
8362306a36Sopenharmony_ci};
84