Root/atusd/tools/lib/atusd.c

Source at commit 86e556ce92af39a3353e0c6494ba20de59d47d4c created 9 years 9 months ago.
By Werner Almesberger, First part of the board bringup: power and clock.
1#include <stdint.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <fcntl.h>
5#include <sys/mman.h>
6
7
8enum {
9    VDD_OFF = 1 << 6, /* VDD disable, PD06 */
10    MxSx = 1 << 8, /* CMD, PD08 */
11    CLK = 1 << 9, /* CLK, PD09 */
12    SCLK = 1 << 10, /* DAT0, PD10 */
13    SLP_TR = 1 << 11, /* DAT1, PD11 */
14    IRQ = 1 << 12, /* DAT2, PD12 */
15    nSEL = 1 << 13, /* DAT3/CD, PD13 */
16};
17
18
19#define SOC_BASE 0x10000000
20
21#define REG(n) (*(volatile uint32_t *) (dsc->mem+(n)))
22
23#define CGU(n) REG(0x00000+(n))
24#define GPIO(n) REG(0x10000+(n))
25#define MSC(n) REG(0x21000+(n))
26
27#define PDDATS GPIO(0x314) /* port D data set */
28#define PDDATC GPIO(0x318) /* port D data clear */
29#define PDFUNS GPIO(0x344) /* port D function set */
30#define PDFUNC GPIO(0x348) /* port D function clear */
31#define PDDIRS GPIO(0x364) /* port D direction set */
32#define PDDIRC GPIO(0x368) /* port D direction clear */
33
34#define MSC_STRPCL MSC(0x00) /* Start/stop MMC/SD clock */
35#define MSC_CLKRT MSC(0x08) /* MSC Clock Rate */
36
37#define CLKGR CGU(0x0020) /* Clock Gate */
38#define MSCCDR CGU(0x0068) /* MSC device clock divider */
39
40
41#define PAGE_SIZE 4096
42
43
44struct atusd_dsc {
45    int fd;
46    void *mem;
47};
48
49
50struct atusd_dsc *atusd_open(void)
51{
52    struct atusd_dsc *dsc;
53
54    dsc = malloc(sizeof(*dsc));
55    if (!dsc) {
56        perror("malloc");
57        exit(1);
58    }
59
60    dsc->fd = open("/dev/mem", O_RDWR);
61    if (dsc->fd < 0) {
62        perror("/dev/mem");
63        exit(1);
64    }
65    dsc->mem = mmap(NULL, PAGE_SIZE*3*16, PROT_READ | PROT_WRITE,
66        MAP_SHARED, dsc->fd, SOC_BASE);
67        if (dsc->mem == MAP_FAILED) {
68                perror("mmap");
69                exit(1);
70        }
71
72    /* set the output levels */
73    PDDATS = nSEL | VDD_OFF;
74    PDDATC = SCLK | SLP_TR;
75
76    /* take the GPIOs away from the MMC controller */
77    PDFUNC = MxSx | SCLK | SLP_TR | IRQ | nSEL;
78    PDFUNS = CLK;
79
80    /* set the pin directions */
81    PDDIRC = IRQ;
82    PDDIRS = MxSx | CLK | SCLK | SLP_TR | nSEL;
83
84    /* enable power */
85    PDDATC = VDD_OFF;
86
87    /* set the MSC clock to 316 MHz / 21 = 16 MHz */
88    MSCCDR = 20;
89    /*
90     * Enable the MSC clock. We need to do this before accessing any
91     * registers of the MSC block !
92     */
93    CLKGR &= ~(1 << 7);
94    /* bus clock = MSC clock / 1 */
95    MSC_CLKRT = 0;
96    /* start MMC clock output */
97    MSC_STRPCL = 2;
98
99    return dsc;
100}
101
102
103void atusd_close(struct atusd_dsc *dsc)
104{
105    /* stop the MMC clock */
106    MSC_STRPCL = 1;
107
108    /* cut the power */
109    PDDATS = VDD_OFF;
110
111    /* make all MMC pins inputs */
112    PDDIRC = MxSx | CLK | SCLK | SLP_TR | IRQ | nSEL;
113}
114

Archive Download this file



interactive