18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: ISC
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#include <linux/kernel.h>
48c2ecf20Sopenharmony_ci#include <linux/module.h>
58c2ecf20Sopenharmony_ci#include <linux/pci.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include "mt7603.h"
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_cistatic const struct pci_device_id mt76pci_device_table[] = {
108c2ecf20Sopenharmony_ci	{ PCI_DEVICE(0x14c3, 0x7603) },
118c2ecf20Sopenharmony_ci	{ },
128c2ecf20Sopenharmony_ci};
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_cistatic int
158c2ecf20Sopenharmony_cimt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
168c2ecf20Sopenharmony_ci{
178c2ecf20Sopenharmony_ci	struct mt7603_dev *dev;
188c2ecf20Sopenharmony_ci	struct mt76_dev *mdev;
198c2ecf20Sopenharmony_ci	int ret;
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	ret = pcim_enable_device(pdev);
228c2ecf20Sopenharmony_ci	if (ret)
238c2ecf20Sopenharmony_ci		return ret;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
268c2ecf20Sopenharmony_ci	if (ret)
278c2ecf20Sopenharmony_ci		return ret;
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	pci_set_master(pdev);
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
328c2ecf20Sopenharmony_ci	if (ret)
338c2ecf20Sopenharmony_ci		return ret;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7603_ops,
368c2ecf20Sopenharmony_ci				 &mt7603_drv_ops);
378c2ecf20Sopenharmony_ci	if (!mdev)
388c2ecf20Sopenharmony_ci		return -ENOMEM;
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	dev = container_of(mdev, struct mt7603_dev, mt76);
418c2ecf20Sopenharmony_ci	mt76_mmio_init(mdev, pcim_iomap_table(pdev)[0]);
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
448c2ecf20Sopenharmony_ci		    (mt76_rr(dev, MT_HW_REV) & 0xff);
458c2ecf20Sopenharmony_ci	dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_INT_MASK_CSR, 0);
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	ret = devm_request_irq(mdev->dev, pdev->irq, mt7603_irq_handler,
508c2ecf20Sopenharmony_ci			       IRQF_SHARED, KBUILD_MODNAME, dev);
518c2ecf20Sopenharmony_ci	if (ret)
528c2ecf20Sopenharmony_ci		goto error;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	ret = mt7603_register_device(dev);
558c2ecf20Sopenharmony_ci	if (ret)
568c2ecf20Sopenharmony_ci		goto error;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	return 0;
598c2ecf20Sopenharmony_cierror:
608c2ecf20Sopenharmony_ci	mt76_free_device(&dev->mt76);
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	return ret;
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cistatic void
668c2ecf20Sopenharmony_cimt76pci_remove(struct pci_dev *pdev)
678c2ecf20Sopenharmony_ci{
688c2ecf20Sopenharmony_ci	struct mt76_dev *mdev = pci_get_drvdata(pdev);
698c2ecf20Sopenharmony_ci	struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	mt7603_unregister_device(dev);
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(pci, mt76pci_device_table);
758c2ecf20Sopenharmony_ciMODULE_FIRMWARE(MT7603_FIRMWARE_E1);
768c2ecf20Sopenharmony_ciMODULE_FIRMWARE(MT7603_FIRMWARE_E2);
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_cistruct pci_driver mt7603_pci_driver = {
798c2ecf20Sopenharmony_ci	.name		= KBUILD_MODNAME,
808c2ecf20Sopenharmony_ci	.id_table	= mt76pci_device_table,
818c2ecf20Sopenharmony_ci	.probe		= mt76pci_probe,
828c2ecf20Sopenharmony_ci	.remove		= mt76pci_remove,
838c2ecf20Sopenharmony_ci};
84