blob: b8419aada6c9e36dc628b702f2ad5ca57eea99f1 [file] [log] [blame]
Sylvain Munautbc9f5c42020-09-14 10:22:29 +02001/*
2 * misc.c
3 *
4 * Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
5 * SPDX-License-Identifier: GPL-3.0-or-later
6 */
7
8#include <stdbool.h>
9#include <stdint.h>
10
11#include "config.h"
12#include "misc.h"
Harald Welte52765672020-12-15 18:35:42 +010013#include "e1.h"
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020014
15
16struct misc {
17 uint32_t warmboot;
Sylvain Munautbe5a53a2022-01-11 11:08:25 +010018 struct {
19 uint16_t oe_out;
20 uint8_t in;
21 uint8_t _rsvd;
22 } gpio;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020023 uint32_t e1_led;
24 uint32_t _rsvd;
25 struct {
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020026 uint16_t rx;
Sylvain Munautc1d117b2020-09-15 21:57:52 +020027 uint16_t tx;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020028 } e1_tick[2];
Sylvain Munaut1ac458f2020-09-15 22:06:00 +020029 struct {
30 uint32_t pps;
31 uint32_t now;
32 } time;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020033 uint32_t pdm[8];
34} __attribute__((packed,aligned(4)));
35
36static volatile struct misc * const misc_regs = (void*)(MISC_BASE);
37
38
39static const int pdm_bits[5] = { 12, 12, 8, 8, 8 };
40
41
42void
43pdm_set(int chan, bool enable, unsigned value, bool normalize)
44{
45 if (normalize)
46 value >>= (16 - pdm_bits[chan]);
47 if (enable)
48 value |= 0x80000000;
49 misc_regs->pdm[chan] = value;
50}
51
52
Sylvain Munaut5e860472020-09-15 22:20:21 +020053void
Sylvain Munautbe5a53a2022-01-11 11:08:25 +010054gpio_dir(int n, bool output)
55{
56 uint16_t mask = 256 << n;
57
58 if (output)
59 misc_regs->gpio.oe_out |= mask;
60 else
61 misc_regs->gpio.oe_out &= ~mask;
62}
63
64void
65gpio_out(int n, bool val)
66{
67 uint16_t mask = 1 << n;
68
69 if (val)
70 misc_regs->gpio.oe_out |= mask;
71 else
72 misc_regs->gpio.oe_out &= ~mask;
73}
74
75bool
76gpio_in(int n)
77{
78 return (misc_regs->gpio.in & (1 << n)) != 0;
79}
80
81
82void
Sylvain Munaut394748a2022-01-11 11:06:28 +010083e1_led_run(void)
84{
85 misc_regs->e1_led |= 0x100;
86}
87
88void
89e1_led_pause(void)
90{
91 misc_regs->e1_led &= 0xff;
92}
93
94void
Sylvain Munaut5e860472020-09-15 22:20:21 +020095e1_led_set(bool enable, uint8_t cfg)
96{
97 misc_regs->e1_led = (enable ? 0x100 : 0x000) | cfg;
98}
99
Harald Welte52765672020-12-15 18:35:42 +0100100void
Sylvain Munaut8f31a9e2022-01-03 22:09:03 +0100101e1_platform_led_set(int port, enum e1_platform_led led,
Harald Welte52765672020-12-15 18:35:42 +0100102 enum e1_platform_led_state state)
103{
104 uint32_t tmp;
105 unsigned int shift;
106
107 if (port >= 2)
108 return;
109
110 shift = 4*port + 2*led;
111
112 tmp = misc_regs->e1_led;
113 tmp &= ~(3 << shift);
Sylvain Munaut394748a2022-01-11 11:06:28 +0100114 tmp |= ((state & 3) << shift);
Harald Welte52765672020-12-15 18:35:42 +0100115 misc_regs->e1_led = tmp;
116}
117
Sylvain Munaut394748a2022-01-11 11:06:28 +0100118
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200119uint16_t
Sylvain Munaut436b7752022-01-03 22:09:54 +0100120e1_tick_read(int port)
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200121{
Sylvain Munaut436b7752022-01-03 22:09:54 +0100122 return misc_regs->e1_tick[port].tx;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200123}
Sylvain Munaut46d6b412020-10-29 13:19:05 +0100124
Sylvain Munaut00b57622022-01-11 11:10:49 +0100125
126bool
127time_elapsed(uint32_t ref, unsigned int tick)
128{
129 return ((misc_regs->time.now - ref) & 0x7fffffff) >= tick;
130}
131
132void
133delay(unsigned int ms)
134{
135 uint32_t ref = misc_regs->time.now;
136 ms *= SYS_CLK_FREQ / 1000;
137 while (!time_elapsed(ref, ms));
138}
139
140uint32_t
141time_pps_read(void)
142{
143 return misc_regs->time.pps;
144}
145
146uint32_t
147time_now_read(void)
148{
149 return misc_regs->time.now;
150}
151
152
Sylvain Munaut46d6b412020-10-29 13:19:05 +0100153void
154reboot(int fw)
155{
156 misc_regs->warmboot = (1 << 2) | (fw << 0);
157}