A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Jens Arnold
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "system.h"
23#include "kernel.h"
24#include "isp1362.h"
25
26#define HC_DATA (*((volatile unsigned short*)0xc0000000))
27#define HC_CMD (*((volatile unsigned short*)0xc0000002))
28#define DC_DATA (*((volatile unsigned short*)0xc0000004))
29#define DC_CMD (*((volatile unsigned short*)0xc0000006))
30
31/* host controller access */
32
33unsigned isp1362_read_hc_reg16(unsigned reg)
34{
35 HC_CMD = reg;
36
37 asm ("nop\n nop\n nop\n nop\n");
38 asm ("nop\n nop\n nop\n nop\n");
39 asm ("nop\n nop\n nop\n nop\n");
40
41 return HC_DATA;
42}
43
44unsigned isp1362_read_hc_reg32(unsigned reg)
45{
46 unsigned data;
47
48 HC_CMD = reg;
49
50 asm ("nop\n nop\n nop\n nop\n");
51 asm ("nop\n nop\n nop\n nop\n");
52 asm ("nop\n nop\n nop\n nop\n");
53
54 data = HC_DATA;
55 data |= HC_DATA << 16;
56 return data;
57}
58
59void isp1362_write_hc_reg16(unsigned reg, unsigned data)
60{
61 HC_CMD = reg | 0x80;
62
63 asm ("nop\n nop\n nop\n");
64
65 HC_DATA = data;
66}
67
68void isp1362_write_hc_reg32(unsigned reg, unsigned data)
69{
70 HC_CMD = reg | 0x80;
71
72 asm ("nop\n nop\n nop\n");
73
74 HC_DATA = data;
75 HC_DATA = data >> 16;
76}
77
78/* device controller access */
79
80unsigned isp1362_read_dc_reg16(unsigned reg)
81{
82 DC_CMD = reg;
83
84 asm ("nop\n nop\n nop\n nop\n");
85 asm ("nop\n nop\n nop\n nop\n");
86 asm ("nop\n nop\n nop\n nop\n");
87
88 return DC_DATA;
89}
90
91unsigned isp1362_read_dc_reg32(unsigned reg)
92{
93 unsigned data;
94
95 DC_CMD = reg;
96
97 asm ("nop\n nop\n nop\n nop\n");
98 asm ("nop\n nop\n nop\n nop\n");
99 asm ("nop\n nop\n nop\n nop\n");
100
101 data = DC_DATA;
102 data |= DC_DATA << 16;
103 return data;
104}
105
106void isp1362_write_dc_reg16(unsigned reg, unsigned data)
107{
108 DC_CMD = reg;
109
110 asm ("nop\n nop\n nop\n");
111
112 DC_DATA = data;
113}
114
115void isp1362_write_dc_reg32(unsigned reg, unsigned data)
116{
117 DC_CMD = reg;
118
119 asm ("nop\n nop\n nop\n");
120
121 DC_DATA = data;
122 DC_DATA = data >> 16;
123}
124
125static void isp1362_suspend(void)
126{
127 unsigned data;
128
129 data = isp1362_read_hc_reg16(ISP1362_OTG_CONTROL);
130 data &= ~0x0001; /* DRV_VBUS = 0 */
131 isp1362_write_hc_reg16(ISP1362_OTG_CONTROL, data);
132
133 /* prepare the DC */
134 data = isp1362_read_dc_reg16(ISP1362_DC_HARDWARE_CONFIG_R);
135 data &= ~0x1008; /* CLKRUN = WKUPCS = 0. Wakeup is still possible via /D_WAKEUP */
136 isp1362_write_dc_reg16(ISP1362_DC_HARDWARE_CONFIG_W, data);
137
138 /* send the DC to sleep */
139 data = isp1362_read_dc_reg16(ISP1362_DC_MODE_R);
140 data |= 0x20; /* GOSUSP = 1 */
141 isp1362_write_dc_reg16(ISP1362_DC_MODE_W, data);
142 data &= ~0x20; /* GOSUSP = 0 */
143 isp1362_write_dc_reg16(ISP1362_DC_MODE_W, data);
144
145 /* prepare the HC */
146 data = isp1362_read_hc_reg16(ISP1362_HC_HARDWARE_CONFIG);
147 data &= ~0x0800; /* SuspendClkNotStop = 0 */
148 data |= 0x4001; /* GlobalPowerDown = InterruptPinEnable = 1 */
149 isp1362_write_hc_reg16(ISP1362_HC_HARDWARE_CONFIG, data);
150
151 /* TODO: OTG wake-up cfg */
152 /* TODO: Interrupt setup */
153
154 /* set the HC to operational */
155 isp1362_write_hc_reg32(ISP1362_HC_CONTROL, 0x0680);
156 /* RWE = RWC = 1, HCFS = 0b10 (USBOperational) */
157 /* ..then send it to sleep */
158 isp1362_write_hc_reg32(ISP1362_HC_CONTROL, 0x06c0);
159 /* RWE = RWC = 1, HCFS = 0b11 (USBSuspend) */
160}
161
162/* init */
163
164void isp1362_init(void)
165{
166 and_l(~0x00200080, &GPIO1_OUT); /* disable 5V USB host power and ??? */
167 or_l( 0x00200080, &GPIO1_ENABLE);
168 or_l( 0x00200080, &GPIO1_FUNCTION);
169
170 or_l( 0x20600000, &GPIO_OUT); /* ID = D_SUSPEND = /OTGMODE = 1 */
171 and_l(~0x04000000, &GPIO_OUT); /* ?R26? = 0 */
172 or_l( 0x24600000, &GPIO_ENABLE); /* ID, ?R26?, D_SUSPEND, /OTGMODE outputs */
173 and_l(~0x000000a8, &GPIO_ENABLE); /* /INT2, /INT1, /RESET inputs */
174 or_l( 0x246000a8, &GPIO_FUNCTION); /* GPIO for these pins */
175
176 sleep(HZ/5);
177
178 isp1362_suspend();
179}