1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#define SDHCI_REG_BAR 0
#include "../dev_sdio_dm.h"
struct pci_sdhci_host
{
struct rt_sdhci_host parent;
};
static const struct rt_sdhci_ops pci_sdhci_ops =
{
.set_clock = rt_sdhci_set_clock,
.set_bus_width = rt_sdhci_set_bus_width,
.reset = rt_sdhci_reset,
};
static rt_err_t pci_sdhci_probe(struct rt_pci_device *pdev)
{
rt_err_t err;
struct rt_sdhci_host *host;
struct pci_sdhci_host *pci_host;
host = rt_sdhci_alloc_host(&pdev->parent, sizeof(struct pci_sdhci_host));
if (!host)
{
return -RT_ENOMEM;
}
pci_host = rt_container_of(host, struct pci_sdhci_host, parent);
host->ioaddr = rt_pci_iomap(pdev, SDHCI_REG_BAR);
if (!host->ioaddr)
{
err = -RT_EIO;
goto _fail;
}
host->irq = pdev->irq;
host->ops = &pci_sdhci_ops;
rt_pci_irq_unmask(pdev);
rt_pci_set_master(pdev);
if ((err = rt_sdhci_set_and_add_host(host)))
{
goto _fail;
}
pdev->parent.user_data = pci_host;
return RT_EOK;
_fail:
if (host->ioaddr)
{
rt_iounmap(host->ioaddr);
}
rt_sdhci_free_host(host);
return err;
}
static rt_err_t pci_sdhci_remove(struct rt_pci_device *pdev)
{
rt_bool_t dead;
struct rt_sdhci_host *host;
struct pci_sdhci_host *pci_host = pdev->parent.user_data;
host = &pci_host->parent;
/* INTx is shared, don't mask all */
rt_hw_interrupt_umask(pdev->irq);
rt_pci_irq_mask(pdev);
rt_pci_clear_master(pdev);
dead = (HWREG32(host->ioaddr + RT_SDHCI_INT_STATUS) == 0xffffffff);
rt_sdhci_uninit_host(host, dead);
rt_iounmap(host->ioaddr);
rt_sdhci_free_host(host);
return RT_EOK;
}
static const struct rt_pci_device_id pci_sdhci_pci_ids[] =
{
{ RT_PCI_DEVICE_ID(PCI_VENDOR_ID_REDHAT, 0x0007), },
{ RT_PCI_DEVICE_CLASS(PCIS_SYSTEM_SDHCI, ~0) },
{ /* sentinel */ }
};
static struct rt_pci_driver pci_sdhci_driver =
{
.name = "sdhci-pci",
.ids = pci_sdhci_pci_ids,
.probe = pci_sdhci_probe,
.remove = pci_sdhci_remove,
};
RT_PCI_DRIVER_EXPORT(pci_sdhci_driver);
|