aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2021-10-22 00:49:58 +0100
committerGitHub <noreply@github.com>2021-10-22 00:49:58 +0100
commit0093d3d761e60a31bb2a15a5859dbd0c08ef9999 (patch)
tree144db2e99236bd0fc2654cbeaecc57bbb5409b39
parent1b1f3ec68ee1e7abe436a46bcfedf30f21330aef (diff)
downloadqmk_firmware-0093d3d761e60a31bb2a15a5859dbd0c08ef9999.tar.gz
qmk_firmware-0093d3d761e60a31bb2a15a5859dbd0c08ef9999.zip
Initial USB2422 driver (#14835)
-rw-r--r--drivers/usb2422.c (renamed from tmk_core/protocol/arm_atsam/usb/usb2422.h)216
-rw-r--r--drivers/usb2422.h59
-rw-r--r--keyboards/massdrop/alt/alt.h2
-rw-r--r--keyboards/massdrop/alt/config.h9
-rw-r--r--keyboards/massdrop/ctrl/config.h9
-rw-r--r--keyboards/massdrop/ctrl/ctrl.h2
-rw-r--r--tmk_core/protocol/arm_atsam.mk4
-rw-r--r--tmk_core/protocol/arm_atsam/arm_atsam_protocol.h2
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c19
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.h9
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c4
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_hub.c (renamed from tmk_core/protocol/arm_atsam/usb/usb2422.c)98
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_hub.h51
13 files changed, 278 insertions, 206 deletions
diff --git a/tmk_core/protocol/arm_atsam/usb/usb2422.h b/drivers/usb2422.c
index b4830b5bc..62b919093 100644
--- a/tmk_core/protocol/arm_atsam/usb/usb2422.h
+++ b/drivers/usb2422.c
@@ -1,32 +1,25 @@
1/* 1/* Copyright 2021 QMK
2Copyright 2018 Massdrop Inc. 2 *
3 3 * This program is free software: you can redistribute it and/or modify
4This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by
5it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or
6the Free Software Foundation, either version 2 of the License, or 6 * (at your option) any later version.
7(at your option) any later version. 7 *
8 8 * This program is distributed in the hope that it will be useful,
9This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details.
12GNU General Public License for more details. 12 *
13 13 * You should have received a copy of the GNU General Public License
14You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */
16*/ 16#include <string.h>
17 17#include "usb2422.h"
18#ifndef _USB2422_H_ 18#include "i2c_master.h"
19#define _USB2422_H_ 19#include "wait.h"
20 20#include "gpio.h"
21#define REV_USB2422 0x100
22
23#define USB2422_ADDR 0x58 // I2C device address, one instance
24
25#define USB2422_HUB_ACTIVE_GROUP 0 // PA
26#define USB2422_HUB_ACTIVE_PIN 18 // 18
27 21
28/* -------- USB2422_VID : (USB2422L Offset: 0x00) (R/W 16) Vendor ID -------- */ 22/* -------- USB2422_VID : (USB2422L Offset: 0x00) (R/W 16) Vendor ID -------- */
29#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
30typedef union { 23typedef union {
31 struct { 24 struct {
32 uint16_t VID_LSB : 8; 25 uint16_t VID_LSB : 8;
@@ -34,10 +27,8 @@ typedef union {
34 } bit; /*!< Structure used for bit access */ 27 } bit; /*!< Structure used for bit access */
35 uint16_t reg; /*!< Type used for register access */ 28 uint16_t reg; /*!< Type used for register access */
36} USB2422_VID_Type; 29} USB2422_VID_Type;
37#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
38 30
39/* -------- USB2422_PID : (USB2422L Offset: 0x02) (R/W 16) Product ID -------- */ 31/* -------- USB2422_PID : (USB2422L Offset: 0x02) (R/W 16) Product ID -------- */
40#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
41typedef union { 32typedef union {
42 struct { 33 struct {
43 uint16_t PID_LSB : 8; 34 uint16_t PID_LSB : 8;
@@ -45,10 +36,8 @@ typedef union {
45 } bit; /*!< Structure used for bit access */ 36 } bit; /*!< Structure used for bit access */
46 uint16_t reg; /*!< Type used for register access */ 37 uint16_t reg; /*!< Type used for register access */
47} USB2422_PID_Type; 38} USB2422_PID_Type;
48#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
49 39
50/* -------- USB2422_DID : (USB2422L Offset: 0x04) (R/W 16) Device ID -------- */ 40/* -------- USB2422_DID : (USB2422L Offset: 0x04) (R/W 16) Device ID -------- */
51#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
52typedef union { 41typedef union {
53 struct { 42 struct {
54 uint16_t DID_LSB : 8; 43 uint16_t DID_LSB : 8;
@@ -56,10 +45,8 @@ typedef union {
56 } bit; /*!< Structure used for bit access */ 45 } bit; /*!< Structure used for bit access */
57 uint16_t reg; /*!< Type used for register access */ 46 uint16_t reg; /*!< Type used for register access */
58} USB2422_DID_Type; 47} USB2422_DID_Type;
59#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
60 48
61/* -------- USB2422_CFG1 : (USB2422L Offset: 0x06) (R/W 8) Configuration Data Byte 1-------- */ 49/* -------- USB2422_CFG1 : (USB2422L Offset: 0x06) (R/W 8) Configuration Data Byte 1-------- */
62#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
63typedef union { 50typedef union {
64 struct { 51 struct {
65 uint8_t PORT_PWR : 1; 52 uint8_t PORT_PWR : 1;
@@ -72,10 +59,8 @@ typedef union {
72 } bit; /*!< Structure used for bit access */ 59 } bit; /*!< Structure used for bit access */
73 uint8_t reg; /*!< Type used for register access */ 60 uint8_t reg; /*!< Type used for register access */
74} USB2422_CFG1_Type; 61} USB2422_CFG1_Type;
75#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
76 62
77/* -------- USB2422_CFG2 : (USB2422L Offset: 0x07) (R/W 8) Configuration Data Byte 2-------- */ 63/* -------- USB2422_CFG2 : (USB2422L Offset: 0x07) (R/W 8) Configuration Data Byte 2-------- */
78#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
79typedef union { 64typedef union {
80 struct { 65 struct {
81 uint8_t : 3; 66 uint8_t : 3;
@@ -86,10 +71,8 @@ typedef union {
86 } bit; /*!< Structure used for bit access */ 71 } bit; /*!< Structure used for bit access */
87 uint8_t reg; /*!< Type used for register access */ 72 uint8_t reg; /*!< Type used for register access */
88} USB2422_CFG2_Type; 73} USB2422_CFG2_Type;
89#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
90 74
91/* -------- USB2422_CFG3 : (USB2422L Offset: 0x08) (R/W 16) Configuration Data Byte 3-------- */ 75/* -------- USB2422_CFG3 : (USB2422L Offset: 0x08) (R/W 16) Configuration Data Byte 3-------- */
92#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
93typedef union { 76typedef union {
94 struct { 77 struct {
95 uint8_t STRING_EN : 1; 78 uint8_t STRING_EN : 1;
@@ -99,10 +82,8 @@ typedef union {
99 } bit; /*!< Structure used for bit access */ 82 } bit; /*!< Structure used for bit access */
100 uint8_t reg; /*!< Type used for register access */ 83 uint8_t reg; /*!< Type used for register access */
101} USB2422_CFG3_Type; 84} USB2422_CFG3_Type;
102#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
103 85
104/* -------- USB2422_NRD : (USB2422L Offset: 0x09) (R/W 8) Non Removable Device -------- */ 86/* -------- USB2422_NRD : (USB2422L Offset: 0x09) (R/W 8) Non Removable Device -------- */
105#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
106typedef union { 87typedef union {
107 struct { 88 struct {
108 uint8_t : 5; 89 uint8_t : 5;
@@ -112,10 +93,8 @@ typedef union {
112 } bit; /*!< Structure used for bit access */ 93 } bit; /*!< Structure used for bit access */
113 uint8_t reg; /*!< Type used for register access */ 94 uint8_t reg; /*!< Type used for register access */
114} USB2422_NRD_Type; 95} USB2422_NRD_Type;
115#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
116 96
117/* -------- USB2422_PDS : (USB2422L Offset: 0x0A) (R/W 8) Port Diable for Self-Powered Operation -------- */ 97/* -------- USB2422_PDS : (USB2422L Offset: 0x0A) (R/W 8) Port Diable for Self-Powered Operation -------- */
118#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
119typedef union { 98typedef union {
120 struct { 99 struct {
121 uint8_t : 1; 100 uint8_t : 1;
@@ -125,10 +104,9 @@ typedef union {
125 } bit; /*!< Structure used for bit access */ 104 } bit; /*!< Structure used for bit access */
126 uint8_t reg; /*!< Type used for register access */ 105 uint8_t reg; /*!< Type used for register access */
127} USB2422_PDS_Type; 106} USB2422_PDS_Type;
128#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
129 107
130/* -------- USB2422_PDB : (USB2422L Offset: 0x0B) (R/W 8) Port Diable for Bus-Powered Operation -------- */ 108/* -------- USB2422_PDB : (USB2422L Offset: 0x0B) (R/W 8) Port Diable for Bus-Powered Operation -------- */
131#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) 109
132typedef union { 110typedef union {
133 struct { 111 struct {
134 uint8_t : 1; 112 uint8_t : 1;
@@ -138,125 +116,98 @@ typedef union {
138 } bit; /*!< Structure used for bit access */ 116 } bit; /*!< Structure used for bit access */
139 uint8_t reg; /*!< Type used for register access */ 117 uint8_t reg; /*!< Type used for register access */
140} USB2422_PDB_Type; 118} USB2422_PDB_Type;
141#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
142 119
143/* -------- USB2422_MAXPS : (USB2422L Offset: 0x0C) (R/W 8) Max Power for Self-Powered Operation -------- */ 120/* -------- USB2422_MAXPS : (USB2422L Offset: 0x0C) (R/W 8) Max Power for Self-Powered Operation -------- */
144#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
145typedef union { 121typedef union {
146 struct { 122 struct {
147 uint8_t MAX_PWR_SP : 8; 123 uint8_t MAX_PWR_SP : 8;
148 } bit; /*!< Structure used for bit access */ 124 } bit; /*!< Structure used for bit access */
149 uint8_t reg; /*!< Type used for register access */ 125 uint8_t reg; /*!< Type used for register access */
150} USB2422_MAXPS_Type; 126} USB2422_MAXPS_Type;
151#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
152 127
153/* -------- USB2422_MAXPB : (USB2422L Offset: 0x0D) (R/W 8) Max Power for Bus-Powered Operation -------- */ 128/* -------- USB2422_MAXPB : (USB2422L Offset: 0x0D) (R/W 8) Max Power for Bus-Powered Operation -------- */
154#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
155typedef union { 129typedef union {
156 struct { 130 struct {
157 uint8_t MAX_PWR_BP : 8; 131 uint8_t MAX_PWR_BP : 8;
158 } bit; /*!< Structure used for bit access */ 132 } bit; /*!< Structure used for bit access */
159 uint8_t reg; /*!< Type used for register access */ 133 uint8_t reg; /*!< Type used for register access */
160} USB2422_MAXPB_Type; 134} USB2422_MAXPB_Type;
161#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
162 135
163/* -------- USB2422_HCMCS : (USB2422L Offset: 0x0E) (R/W 8) Hub Controller Max Current for Self-Powered Operation -------- */ 136/* -------- USB2422_HCMCS : (USB2422L Offset: 0x0E) (R/W 8) Hub Controller Max Current for Self-Powered Operation -------- */
164#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
165typedef union { 137typedef union {
166 struct { 138 struct {
167 uint8_t HC_MAX_C_SP : 8; 139 uint8_t HC_MAX_C_SP : 8;
168 } bit; /*!< Structure used for bit access */ 140 } bit; /*!< Structure used for bit access */
169 uint8_t reg; /*!< Type used for register access */ 141 uint8_t reg; /*!< Type used for register access */
170} USB2422_HCMCS_Type; 142} USB2422_HCMCS_Type;
171#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
172 143
173/* -------- USB2422_HCMCB : (USB2422L Offset: 0x0F) (R/W 8) Hub Controller Max Current for Bus-Powered Operation -------- */ 144/* -------- USB2422_HCMCB : (USB2422L Offset: 0x0F) (R/W 8) Hub Controller Max Current for Bus-Powered Operation -------- */
174#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
175typedef union { 145typedef union {
176 struct { 146 struct {
177 uint8_t HC_MAX_C_BP : 8; 147 uint8_t HC_MAX_C_BP : 8;
178 } bit; /*!< Structure used for bit access */ 148 } bit; /*!< Structure used for bit access */
179 uint8_t reg; /*!< Type used for register access */ 149 uint8_t reg; /*!< Type used for register access */
180} USB2422_HCMCB_Type; 150} USB2422_HCMCB_Type;
181#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
182 151
183/* -------- USB2422_PWRT : (USB2422L Offset: 0x10) (R/W 8) Power On Time -------- */ 152/* -------- USB2422_PWRT : (USB2422L Offset: 0x10) (R/W 8) Power On Time -------- */
184#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
185typedef union { 153typedef union {
186 struct { 154 struct {
187 uint8_t POWER_ON_TIME : 8; 155 uint8_t POWER_ON_TIME : 8;
188 } bit; /*!< Structure used for bit access */ 156 } bit; /*!< Structure used for bit access */
189 uint8_t reg; /*!< Type used for register access */ 157 uint8_t reg; /*!< Type used for register access */
190} USB2422_PWRT_Type; 158} USB2422_PWRT_Type;
191#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
192 159
193/* -------- USB2422_LANGID LSB : (USB2422L Offset: 0x11) (R/W 16) Language ID -------- */ 160/* -------- USB2422_LANGID LSB : (USB2422L Offset: 0x11) (R/W 16) Language ID -------- */
194#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
195typedef union { 161typedef union {
196 struct { 162 struct {
197 uint8_t LANGID_LSB : 8; 163 uint8_t LANGID_LSB : 8;
198 } bit; /*!< Structure used for bit access */ 164 } bit; /*!< Structure used for bit access */
199 uint8_t reg; /*!< Type used for register access */ 165 uint8_t reg; /*!< Type used for register access */
200} USB2422_LANGID_LSB_Type; 166} USB2422_LANGID_LSB_Type;
201#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
202 167
203/* -------- USB2422_LANGID MSB : (USB2422L Offset: 0x12) (R/W 16) Language ID -------- */ 168/* -------- USB2422_LANGID MSB : (USB2422L Offset: 0x12) (R/W 16) Language ID -------- */
204#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
205typedef union { 169typedef union {
206 struct { 170 struct {
207 uint8_t LANGID_MSB : 8; 171 uint8_t LANGID_MSB : 8;
208 } bit; /*!< Structure used for bit access */ 172 } bit; /*!< Structure used for bit access */
209 uint8_t reg; /*!< Type used for register access */ 173 uint8_t reg; /*!< Type used for register access */
210} USB2422_LANGID_MSB_Type; 174} USB2422_LANGID_MSB_Type;
211#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
212 175
213/* -------- USB2422_MFRSL : (USB2422L Offset: 0x13) (R/W 8) Manufacturer String Length -------- */ 176/* -------- USB2422_MFRSL : (USB2422L Offset: 0x13) (R/W 8) Manufacturer String Length -------- */
214#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
215typedef union { 177typedef union {
216 struct { 178 struct {
217 uint8_t MFR_STR_LEN : 8; 179 uint8_t MFR_STR_LEN : 8;
218 } bit; /*!< Structure used for bit access */ 180 } bit; /*!< Structure used for bit access */
219 uint8_t reg; /*!< Type used for register access */ 181 uint8_t reg; /*!< Type used for register access */
220} USB2422_MFRSL_Type; 182} USB2422_MFRSL_Type;
221#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
222 183
223/* -------- USB2422_PRDSL : (USB2422L Offset: 0x14) (R/W 8) Product String Length -------- */ 184/* -------- USB2422_PRDSL : (USB2422L Offset: 0x14) (R/W 8) Product String Length -------- */
224#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
225typedef union { 185typedef union {
226 struct { 186 struct {
227 uint8_t PRD_STR_LEN : 8; 187 uint8_t PRD_STR_LEN : 8;
228 } bit; /*!< Structure used for bit access */ 188 } bit; /*!< Structure used for bit access */
229 uint8_t reg; /*!< Type used for register access */ 189 uint8_t reg; /*!< Type used for register access */
230} USB2422_PRDSL_Type; 190} USB2422_PRDSL_Type;
231#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
232 191
233/* -------- USB2422_SERSL : (USB2422L Offset: 0x15) (R/W 8) Serial String Length -------- */ 192/* -------- USB2422_SERSL : (USB2422L Offset: 0x15) (R/W 8) Serial String Length -------- */
234#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
235typedef union { 193typedef union {
236 struct { 194 struct {
237 uint8_t SER_STR_LEN : 8; 195 uint8_t SER_STR_LEN : 8;
238 } bit; /*!< Structure used for bit access */ 196 } bit; /*!< Structure used for bit access */
239 uint8_t reg; /*!< Type used for register access */ 197 uint8_t reg; /*!< Type used for register access */
240} USB2422_SERSL_Type; 198} USB2422_SERSL_Type;
241#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
242 199
243/* -------- USB2422_MFRSTR : (USB2422L Offset: 0x16-53) (R/W 8) Maufacturer String -------- */ 200/* -------- USB2422_MFRSTR : (USB2422L Offset: 0x16-53) (R/W 8) Maufacturer String -------- */
244#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
245typedef uint16_t USB2422_MFRSTR_Type; 201typedef uint16_t USB2422_MFRSTR_Type;
246#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
247 202
248/* -------- USB2422_PRDSTR : (USB2422L Offset: 0x54-91) (R/W 8) Product String -------- */ 203/* -------- USB2422_PRDSTR : (USB2422L Offset: 0x54-91) (R/W 8) Product String -------- */
249#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
250typedef uint16_t USB2422_PRDSTR_Type; 204typedef uint16_t USB2422_PRDSTR_Type;
251#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
252 205
253/* -------- USB2422_SERSTR : (USB2422L Offset: 0x92-CF) (R/W 8) Serial String -------- */ 206/* -------- USB2422_SERSTR : (USB2422L Offset: 0x92-CF) (R/W 8) Serial String -------- */
254#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
255typedef uint16_t USB2422_SERSTR_Type; 207typedef uint16_t USB2422_SERSTR_Type;
256#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
257 208
258/* -------- USB2422_BCEN : (USB2422L Offset: 0xD0) (R/W 8) Battery Charging Enable -------- */ 209/* -------- USB2422_BCEN : (USB2422L Offset: 0xD0) (R/W 8) Battery Charging Enable -------- */
259#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) 210
260typedef union { 211typedef union {
261 struct { 212 struct {
262 uint8_t : 1; 213 uint8_t : 1;
@@ -266,10 +217,8 @@ typedef union {
266 } bit; /*!< Structure used for bit access */ 217 } bit; /*!< Structure used for bit access */
267 uint8_t reg; /*!< Type used for register access */ 218 uint8_t reg; /*!< Type used for register access */
268} USB2422_BCEN_Type; 219} USB2422_BCEN_Type;
269#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
270 220
271/* -------- USB2422_BOOSTUP : (USB2422L Offset: 0xF6) (R/W 8) Boost Upstream -------- */ 221/* -------- USB2422_BOOSTUP : (USB2422L Offset: 0xF6) (R/W 8) Boost Upstream -------- */
272#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
273typedef union { 222typedef union {
274 struct { 223 struct {
275 uint8_t BOOST : 2; 224 uint8_t BOOST : 2;
@@ -277,10 +226,8 @@ typedef union {
277 } bit; /*!< Structure used for bit access */ 226 } bit; /*!< Structure used for bit access */
278 uint8_t reg; /*!< Type used for register access */ 227 uint8_t reg; /*!< Type used for register access */
279} USB2422_BOOSTUP_Type; 228} USB2422_BOOSTUP_Type;
280#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
281 229
282/* -------- USB2422_BOOSTDOWN : (USB2422L Offset: 0xF8) (R/W 8) Boost Downstream -------- */ 230/* -------- USB2422_BOOSTDOWN : (USB2422L Offset: 0xF8) (R/W 8) Boost Downstream -------- */
283#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
284typedef union { 231typedef union {
285 struct { 232 struct {
286 uint8_t BOOST1 : 2; 233 uint8_t BOOST1 : 2;
@@ -289,10 +236,8 @@ typedef union {
289 } bit; /*!< Structure used for bit access */ 236 } bit; /*!< Structure used for bit access */
290 uint8_t reg; /*!< Type used for register access */ 237 uint8_t reg; /*!< Type used for register access */
291} USB2422_BOOSTDOWN_Type; 238} USB2422_BOOSTDOWN_Type;
292#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
293 239
294/* -------- USB2422_PRTSP : (USB2422L Offset: 0xFA) (R/W 8) Port Swap -------- */ 240/* -------- USB2422_PRTSP : (USB2422L Offset: 0xFA) (R/W 8) Port Swap -------- */
295#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
296typedef union { 241typedef union {
297 struct { 242 struct {
298 uint8_t : 1; 243 uint8_t : 1;
@@ -302,10 +247,8 @@ typedef union {
302 } bit; /*!< Structure used for bit access */ 247 } bit; /*!< Structure used for bit access */
303 uint8_t reg; /*!< Type used for register access */ 248 uint8_t reg; /*!< Type used for register access */
304} USB2422_PRTSP_Type; 249} USB2422_PRTSP_Type;
305#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
306 250
307/* -------- USB2422_PRTR12 : (USB2422L Offset: 0xFB) (R/W 8) Port 1/2 Remap -------- */ 251/* -------- USB2422_PRTR12 : (USB2422L Offset: 0xFB) (R/W 8) Port 1/2 Remap -------- */
308#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
309typedef union { 252typedef union {
310 struct { 253 struct {
311 uint8_t PORT1_REMAP : 4; 254 uint8_t PORT1_REMAP : 4;
@@ -313,7 +256,7 @@ typedef union {
313 } bit; /*!< Structure used for bit access */ 256 } bit; /*!< Structure used for bit access */
314 uint8_t reg; /*!< Type used for register access */ 257 uint8_t reg; /*!< Type used for register access */
315} USB2422_PRTR12_Type; 258} USB2422_PRTR12_Type;
316#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ 259
317#define USB2422_PRTR12_DISABLE 0 260#define USB2422_PRTR12_DISABLE 0
318#define USB2422_PRT12_P2TOL1 1 261#define USB2422_PRT12_P2TOL1 1
319#define USB2422_PRT12_P2XTOL2 2 262#define USB2422_PRT12_P2XTOL2 2
@@ -321,7 +264,6 @@ typedef union {
321#define USB2422_PRT12_P1XTOL2 2 264#define USB2422_PRT12_P1XTOL2 2
322 265
323/* -------- USB2422_STCD : (USB2422L Offset: 0xFF) (R/W 8) Status Command -------- */ 266/* -------- USB2422_STCD : (USB2422L Offset: 0xFF) (R/W 8) Status Command -------- */
324#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
325typedef union { 267typedef union {
326 struct { 268 struct {
327 uint8_t USB_ATTACH : 1; 269 uint8_t USB_ATTACH : 1;
@@ -331,10 +273,8 @@ typedef union {
331 } bit; /*!< Structure used for bit access */ 273 } bit; /*!< Structure used for bit access */
332 uint8_t reg; /*!< Type used for register access */ 274 uint8_t reg; /*!< Type used for register access */
333} USB2422_STCD_Type; 275} USB2422_STCD_Type;
334#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
335 276
336/** \brief USB2422 device hardware registers */ 277/** \brief USB2422 device hardware registers */
337#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
338typedef struct { 278typedef struct {
339 USB2422_VID_Type VID; /**< \brief Offset: 0x00*/ 279 USB2422_VID_Type VID; /**< \brief Offset: 0x00*/
340 USB2422_PID_Type PID; /**< \brief Offset: 0x02*/ 280 USB2422_PID_Type PID; /**< \brief Offset: 0x02*/
@@ -368,35 +308,95 @@ typedef struct {
368 USB2422_PRTR12_Type PRTR12; /**< \brief Offset: 0xFB*/ 308 USB2422_PRTR12_Type PRTR12; /**< \brief Offset: 0xFB*/
369 uint8_t Reserved4[0x3]; 309 uint8_t Reserved4[0x3];
370 USB2422_STCD_Type STCD; /**< \brief Offset: 0xFF*/ 310 USB2422_STCD_Type STCD; /**< \brief Offset: 0xFF*/
371} Usb2422; 311} Usb2422_t;
372#endif 312
313// ***************************************************************
314
315static Usb2422_t config;
373 316
374#define PORT_DETECT_RETRY_INTERVAL 2000 317// ***************************************************************
375 318
376#define USB_EXTRA_ADC_THRESHOLD 900 319/** \brief Handle the conversion to allow simple strings
320 */
321static void USB2422_strcpy(const char* str, USB2422_MFRSTR_Type* dest, uint8_t len) {
322 for (uint8_t i = 0; i < len; i++) {
323 dest[i] = str[i];
324 }
325}
377 326
378#define USB_EXTRA_STATE_DISABLED 0 327/** \brief Handle the conversion to allow simple strings
379#define USB_EXTRA_STATE_ENABLED 1 328 */
380#define USB_EXTRA_STATE_UNKNOWN 2 329static void USB2422_write_block(void) {
381#define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3 330 static unsigned char i2c0_buf[34];
382 331
383#define USB_HOST_PORT_1 0 332 unsigned char* dest = i2c0_buf;
384#define USB_HOST_PORT_2 1 333 unsigned char* src;
385#define USB_HOST_PORT_UNKNOWN 2 334 unsigned char* base = (unsigned char*)&config;
386 335
387extern uint8_t usb_host_port; 336 for (src = base; src < base + 256; src += 32) {
388extern uint8_t usb_extra_state; 337 dest[0] = src - base;
389extern uint8_t usb_extra_manual; 338 dest[1] = 32;
390extern uint8_t usb_gcr_auto; 339 memcpy(&dest[2], src, 32);
340 i2c_transmit(USB2422_ADDRESS, dest, 34, 50000);
341 wait_us(100);
342 }
343}
391 344
392void USB2422_init(void); 345// ***************************************************************
393void USB_reset(void);
394void USB_configure(void);
395uint16_t USB_active(void);
396void USB_set_host_by_voltage(void);
397uint16_t adc_get(uint8_t muxpos);
398uint8_t USB2422_Port_Detect_Init(void);
399void USB_HandleExtraDevice(void);
400void USB_ExtraSetState(uint8_t state);
401 346
402#endif //_USB2422_H_ 347void USB2422_init() {
348#ifdef USB2422_RESET_PIN
349 setPinOutput(USB2422_RESET_PIN);
350#endif
351#ifdef USB2422_ACTIVE_PIN
352 setPinInput(USB2422_ACTIVE_PIN);
353#endif
354
355 i2c_init(); // IC2 clk must be high at USB2422 reset release time to signal SMB configuration
356}
357
358void USB2422_configure() {
359 static const char SERNAME[] = "Unavailable";
360
361 memset(&config, 0, sizeof(Usb2422_t));
362
363 // configure Usb2422 registers
364 config.VID.reg = USB2422_VENDOR_ID;
365 config.PID.reg = USB2422_PRODUCT_ID;
366 config.DID.reg = USB2422_DEVICE_VER; // BCD format, eg 01.01
367 config.CFG1.bit.SELF_BUS_PWR = 1; // self powered for now
368 config.CFG1.bit.HS_DISABLE = 1; // full or high speed
369 // config.CFG2.bit.COMPOUND = 0; // compound device
370 config.CFG3.bit.STRING_EN = 1; // strings enabled
371 // config.NRD.bit.PORT2_NR = 0; // MCU is non-removable
372 config.MAXPB.reg = 20; // 0mA
373 config.HCMCB.reg = 20; // 0mA
374 config.MFRSL.reg = sizeof(USB2422_MANUFACTURER);
375 config.PRDSL.reg = sizeof(USB2422_PRODUCT);
376 config.SERSL.reg = sizeof(SERNAME);
377 USB2422_strcpy(USB2422_MANUFACTURER, config.MFRSTR, sizeof(USB2422_MANUFACTURER));
378 USB2422_strcpy(USB2422_PRODUCT, config.PRDSTR, sizeof(USB2422_PRODUCT));
379 USB2422_strcpy(SERNAME, config.SERSTR, sizeof(SERNAME));
380 // config.BOOSTUP.bit.BOOST=3; //upstream port
381 // config.BOOSTDOWN.bit.BOOST1=0; // extra port
382 // config.BOOSTDOWN.bit.BOOST2=2; //MCU is close
383 config.STCD.bit.USB_ATTACH = 1;
384
385 USB2422_write_block();
386}
387
388void USB2422_reset() {
389#ifdef USB2422_RESET_PIN
390 writePinLow(USB2422_RESET_PIN);
391 wait_us(2);
392 writePinHigh(USB2422_RESET_PIN);
393#endif
394}
395
396bool USB2422_active() {
397#ifdef USB2422_ACTIVE_PIN
398 return readPin(USB2422_ACTIVE_PIN);
399#else
400 return 1;
401#endif
402}
diff --git a/drivers/usb2422.h b/drivers/usb2422.h
new file mode 100644
index 000000000..2e435b02b
--- /dev/null
+++ b/drivers/usb2422.h
@@ -0,0 +1,59 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#include <stdbool.h>
19
20#ifndef USB2422_ADDRESS
21# define USB2422_ADDRESS 0x58
22#endif
23
24#ifndef USB2422_VENDOR_ID
25# define USB2422_VENDOR_ID 0xFEED
26#endif
27#ifndef USB2422_PRODUCT_ID
28# define USB2422_PRODUCT_ID 0x0001
29#endif
30#ifndef USB2422_DEVICE_VER
31# define USB2422_DEVICE_VER 0x0001
32#endif
33
34#ifndef USB2422_MANUFACTURER
35# define USB2422_MANUFACTURER "QMK"
36#endif
37#ifndef USB2422_PRODUCT
38# define USB2422_PRODUCT "QMK Hub"
39#endif
40
41/** \brief Initialises the dependent subsystems */
42void USB2422_init(void);
43
44/** \brief Push configuration to the USB2422 device */
45void USB2422_configure(void);
46
47/** \brief Reset the chip (RESET_N)
48 *
49 * NOTE:
50 * Depends on a valid USB2422_RESET_PIN configuration
51 */
52void USB2422_reset(void);
53
54/** \brief Indicates the USB state of the hub (SUSP_IND)
55 *
56 * NOTE:
57 * Depends on a valid USB2422_ACTIVE_PIN configuration
58 */
59bool USB2422_active(void);
diff --git a/keyboards/massdrop/alt/alt.h b/keyboards/massdrop/alt/alt.h
index 039609545..c3761bee8 100644
--- a/keyboards/massdrop/alt/alt.h
+++ b/keyboards/massdrop/alt/alt.h
@@ -7,7 +7,7 @@
7#include "i2c_master.h" 7#include "i2c_master.h"
8#include "md_rgb_matrix.h" //For led keycodes 8#include "md_rgb_matrix.h" //For led keycodes
9#include "usb/udi_cdc.h" 9#include "usb/udi_cdc.h"
10#include "usb/usb2422.h" 10#include "usb/usb_hub.h"
11 11
12#define LAYOUT_65_ansi_blocker( \ 12#define LAYOUT_65_ansi_blocker( \
13 K01, K02, K03, K04, K05, K06, K07, K08, K09, K10, K11, K12, K13, K14, K15, \ 13 K01, K02, K03, K04, K05, K06, K07, K08, K09, K10, K11, K12, K13, K14, K15, \
diff --git a/keyboards/massdrop/alt/config.h b/keyboards/massdrop/alt/config.h
index 085e1aebb..c37949a74 100644
--- a/keyboards/massdrop/alt/config.h
+++ b/keyboards/massdrop/alt/config.h
@@ -90,6 +90,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
90#define DEBUG_BOOT_TRACING_PORT PB 90#define DEBUG_BOOT_TRACING_PORT PB
91#define DEBUG_BOOT_TRACING_PIN 23 91#define DEBUG_BOOT_TRACING_PIN 23
92 92
93/* USB2422 config */
94#define USB2422_ADDRESS 0x58
95#define USB2422_VENDOR_ID 0x04D8
96#define USB2422_PRODUCT_ID 0xEEC5
97#define USB2422_DEVICE_VER 0x0101
98#define USB2422_MANUFACTURER "Massdrop Inc."
99#define USB2422_PRODUCT "Massdrop Hub"
100#define USB2422_ACTIVE_PIN A18
101
93/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ 102/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
94#define DEBOUNCE 5 103#define DEBOUNCE 5
95 104
diff --git a/keyboards/massdrop/ctrl/config.h b/keyboards/massdrop/ctrl/config.h
index aefb90044..fe8b60023 100644
--- a/keyboards/massdrop/ctrl/config.h
+++ b/keyboards/massdrop/ctrl/config.h
@@ -89,6 +89,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
89#define DEBUG_BOOT_TRACING_PORT PB 89#define DEBUG_BOOT_TRACING_PORT PB
90#define DEBUG_BOOT_TRACING_PIN 23 90#define DEBUG_BOOT_TRACING_PIN 23
91 91
92/* USB2422 config */
93#define USB2422_ADDRESS 0x58
94#define USB2422_VENDOR_ID 0x04D8
95#define USB2422_PRODUCT_ID 0xEEC5
96#define USB2422_DEVICE_VER 0x0101
97#define USB2422_MANUFACTURER "Massdrop Inc."
98#define USB2422_PRODUCT "Massdrop Hub"
99#define USB2422_ACTIVE_PIN A18
100
92/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ 101/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
93#define DEBOUNCE 5 102#define DEBOUNCE 5
94 103
diff --git a/keyboards/massdrop/ctrl/ctrl.h b/keyboards/massdrop/ctrl/ctrl.h
index 1650beb9a..a3d66ba77 100644
--- a/keyboards/massdrop/ctrl/ctrl.h
+++ b/keyboards/massdrop/ctrl/ctrl.h
@@ -7,7 +7,7 @@
7#include "i2c_master.h" 7#include "i2c_master.h"
8#include "md_rgb_matrix.h" //For led keycodes 8#include "md_rgb_matrix.h" //For led keycodes
9#include "usb/udi_cdc.h" 9#include "usb/udi_cdc.h"
10#include "usb/usb2422.h" 10#include "usb/usb_hub.h"
11 11
12#define LAYOUT( \ 12#define LAYOUT( \
13 K01, K02, K03, K04, K05, K06, K07, K08, K09, K10, K11, K12, K13, K14, K15, \ 13 K01, K02, K03, K04, K05, K06, K07, K08, K09, K10, K11, K12, K13, K14, K15, \
diff --git a/tmk_core/protocol/arm_atsam.mk b/tmk_core/protocol/arm_atsam.mk
index e3b550596..ffd1fa9f5 100644
--- a/tmk_core/protocol/arm_atsam.mk
+++ b/tmk_core/protocol/arm_atsam.mk
@@ -20,10 +20,12 @@ SRC += $(ARM_ATSAM_DIR)/usb/udi_hid.c
20SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd.c 20SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd.c
21SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd_desc.c 21SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd_desc.c
22SRC += $(ARM_ATSAM_DIR)/usb/ui.c 22SRC += $(ARM_ATSAM_DIR)/usb/ui.c
23SRC += $(ARM_ATSAM_DIR)/usb/usb2422.c
24SRC += $(ARM_ATSAM_DIR)/usb/usb.c 23SRC += $(ARM_ATSAM_DIR)/usb/usb.c
25SRC += $(ARM_ATSAM_DIR)/usb/usb_device_udd.c 24SRC += $(ARM_ATSAM_DIR)/usb/usb_device_udd.c
25SRC += $(ARM_ATSAM_DIR)/usb/usb_hub.c
26SRC += $(ARM_ATSAM_DIR)/usb/usb_util.c 26SRC += $(ARM_ATSAM_DIR)/usb/usb_util.c
27 27
28SRC += $(DRIVER_PATH)/usb2422.c
29
28# Search Path 30# Search Path
29VPATH += $(TMK_DIR)/$(ARM_ATSAM_DIR) 31VPATH += $(TMK_DIR)/$(ARM_ATSAM_DIR)
diff --git a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
index c3eab39fb..e1749f872 100644
--- a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
+++ b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
@@ -29,7 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
29#include "i2c_master.h" 29#include "i2c_master.h"
30#include "shift_register.h" 30#include "shift_register.h"
31 31
32#include "./usb/usb2422.h" 32#include "./usb/usb_hub.h"
33 33
34#ifndef MD_BOOTLOADER 34#ifndef MD_BOOTLOADER
35 35
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c
index dda2f85b0..af046625f 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.c
+++ b/tmk_core/protocol/arm_atsam/i2c_master.c
@@ -564,4 +564,23 @@ uint8_t i2c_led_q_run(void) {
564 564
565 return 1; 565 return 1;
566} 566}
567
568__attribute__((weak)) void i2c_init(void) {
569 static bool is_initialised = false;
570 if (!is_initialised) {
571 is_initialised = true;
572
573 i2c0_init();
574 }
575}
576
577i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout) {
578 uint8_t ret = i2c0_transmit(address, (uint8_t *)data, length, timeout);
579 SERCOM0->I2CM.CTRLB.bit.CMD = 0x03;
580 while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
581 DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP);
582 }
583 return ret ? I2C_STATUS_SUCCESS : I2C_STATUS_ERROR;
584}
585
567#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE) 586#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h
index 68773f213..e11235d44 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.h
+++ b/tmk_core/protocol/arm_atsam/i2c_master.h
@@ -101,4 +101,13 @@ void i2c0_init(void);
101uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout); 101uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout);
102void i2c0_stop(void); 102void i2c0_stop(void);
103 103
104// Terrible interface compatiblity...
105#define I2C_STATUS_SUCCESS (0)
106#define I2C_STATUS_ERROR (-1)
107
108typedef int16_t i2c_status_t;
109
110void i2c_init(void);
111i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout);
112
104#endif // _I2C_MASTER_H_ 113#endif // _I2C_MASTER_H_
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index 858b4cd9f..1df5112ed 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -296,7 +296,7 @@ int main(void) {
296 296
297 matrix_init(); 297 matrix_init();
298 298
299 USB2422_init(); 299 USB_Hub_init();
300 300
301 DBGC(DC_MAIN_UDC_START_BEGIN); 301 DBGC(DC_MAIN_UDC_START_BEGIN);
302 udc_start(); 302 udc_start();
@@ -306,7 +306,7 @@ int main(void) {
306 CDC_init(); 306 CDC_init();
307 DBGC(DC_MAIN_CDC_INIT_COMPLETE); 307 DBGC(DC_MAIN_CDC_INIT_COMPLETE);
308 308
309 while (USB2422_Port_Detect_Init() == 0) { 309 while (USB_Hub_Port_Detect_Init() == 0) {
310 } 310 }
311 311
312 DBG_LED_OFF; 312 DBG_LED_OFF;
diff --git a/tmk_core/protocol/arm_atsam/usb/usb2422.c b/tmk_core/protocol/arm_atsam/usb/usb_hub.c
index a878cb6b7..c5fd284aa 100644
--- a/tmk_core/protocol/arm_atsam/usb/usb2422.c
+++ b/tmk_core/protocol/arm_atsam/usb/usb_hub.c
@@ -16,25 +16,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#include "arm_atsam_protocol.h" 18#include "arm_atsam_protocol.h"
19#include "drivers/usb2422.h"
19#include <string.h> 20#include <string.h>
20 21
21Usb2422 USB2422_shadow;
22unsigned char i2c0_buf[34];
23
24const uint16_t MFRNAME[] = {'M', 'a', 's', 's', 'd', 'r', 'o', 'p', ' ', 'I', 'n', 'c', '.'}; // Massdrop Inc.
25const uint16_t PRDNAME[] = {'M', 'a', 's', 's', 'd', 'r', 'o', 'p', ' ', 'H', 'u', 'b'}; // Massdrop Hub
26#ifndef MD_BOOTLOADER
27// Serial number reported stops before first found space character or at last found character
28const uint16_t SERNAME[] = {'U', 'n', 'a', 'v', 'a', 'i', 'l', 'a', 'b', 'l', 'e'}; // Unavailable
29#else
30// In production, this field is found, modified, and offset noted as the last 32-bit word in the bootloader space
31// The offset allows the application to use the factory programmed serial (which may differ from the physical serial label)
32// Serial number reported stops before first found space character or when max size is reached
33__attribute__((__aligned__(4))) const uint16_t SERNAME[BOOTLOADER_SERIAL_MAX_SIZE] = {'M', 'D', 'H', 'U', 'B', 'B', 'O', 'O', 'T', 'L', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
34// NOTE: Serial replacer will not write a string longer than given here as a precaution, so give enough
35// space as needed and adjust BOOTLOADER_SERIAL_MAX_SIZE to match amount given
36#endif // MD_BOOTLOADER
37
38uint8_t usb_host_port; 22uint8_t usb_host_port;
39 23
40#ifndef MD_BOOTLOADER 24#ifndef MD_BOOTLOADER
@@ -47,29 +31,7 @@ uint8_t usb_gcr_auto;
47 31
48uint16_t adc_extra; 32uint16_t adc_extra;
49 33
50void USB_write2422_block(void) { 34void USB_Hub_init(void) {
51 unsigned char *dest = i2c0_buf;
52 unsigned char *src;
53 unsigned char *base = (unsigned char *)&USB2422_shadow;
54
55 DBGC(DC_USB_WRITE2422_BLOCK_BEGIN);
56
57 for (src = base; src < base + 256; src += 32) {
58 dest[0] = src - base;
59 dest[1] = 32;
60 memcpy(&dest[2], src, 32);
61 i2c0_transmit(USB2422_ADDR, dest, 34, 50000);
62 SERCOM0->I2CM.CTRLB.bit.CMD = 0x03;
63 while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
64 DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP);
65 }
66 wait_us(100);
67 }
68
69 DBGC(DC_USB_WRITE2422_BLOCK_COMPLETE);
70}
71
72void USB2422_init(void) {
73 Gclk * pgclk = GCLK; 35 Gclk * pgclk = GCLK;
74 Mclk * pmclk = MCLK; 36 Mclk * pmclk = MCLK;
75 Port * pport = PORT; 37 Port * pport = PORT;
@@ -147,9 +109,7 @@ void USB2422_init(void) {
147 pusb->DEVICE.QOSCTRL.bit.DQOS = 2; 109 pusb->DEVICE.QOSCTRL.bit.DQOS = 2;
148 pusb->DEVICE.QOSCTRL.bit.CQOS = 2; 110 pusb->DEVICE.QOSCTRL.bit.CQOS = 2;
149 111
150 pport->Group[USB2422_HUB_ACTIVE_GROUP].PINCFG[USB2422_HUB_ACTIVE_PIN].bit.INEN = 1; 112 USB2422_init();
151
152 i2c0_init(); // IC2 clk must be high at USB2422 reset release time to signal SMB configuration
153 113
154 sr_exp_data.bit.HUB_CONNECT = 1; // connect signal 114 sr_exp_data.bit.HUB_CONNECT = 1; // connect signal
155 sr_exp_data.bit.HUB_RESET_N = 1; // reset high 115 sr_exp_data.bit.HUB_RESET_N = 1; // reset high
@@ -181,62 +141,16 @@ void USB_reset(void) {
181} 141}
182 142
183void USB_configure(void) { 143void USB_configure(void) {
184 Usb2422 *pusb2422 = &USB2422_shadow;
185 memset(pusb2422, 0, sizeof(Usb2422));
186
187 uint16_t *serial_use = (uint16_t *)SERNAME; // Default to use SERNAME from this file
188 uint8_t serial_length = sizeof(SERNAME) / sizeof(uint16_t); // Default to use SERNAME from this file
189#ifndef MD_BOOTLOADER
190 uint32_t serial_ptrloc = (uint32_t)&_srom - 4;
191#else // MD_BOOTLOADER
192 uint32_t serial_ptrloc = (uint32_t)&_erom - 4;
193#endif // MD_BOOTLOADER
194 uint32_t serial_address = *(uint32_t *)serial_ptrloc; // Address of bootloader's serial number if available
195
196 DBGC(DC_USB_CONFIGURE_BEGIN); 144 DBGC(DC_USB_CONFIGURE_BEGIN);
197 145
198 if (serial_address != 0xFFFFFFFF && serial_address < serial_ptrloc) // Check for factory programmed serial address 146 USB2422_configure();
199 {
200 if ((serial_address & 0xFF) % 4 == 0) // Check alignment
201 {
202 serial_use = (uint16_t *)(serial_address);
203 serial_length = 0;
204 while ((*(serial_use + serial_length) > 32 && *(serial_use + serial_length) < 127) && serial_length < BOOTLOADER_SERIAL_MAX_SIZE) {
205 serial_length++;
206 DBGC(DC_USB_CONFIGURE_GET_SERIAL);
207 }
208 }
209 }
210
211 // configure Usb2422 registers
212 pusb2422->VID.reg = 0x04D8; // from Microchip 4/19/2018
213 pusb2422->PID.reg = 0xEEC5; // from Microchip 4/19/2018 = Massdrop, Inc. USB Hub
214 pusb2422->DID.reg = 0x0101; // BCD 01.01
215 pusb2422->CFG1.bit.SELF_BUS_PWR = 1; // self powered for now
216 pusb2422->CFG1.bit.HS_DISABLE = 1; // full or high speed
217 // pusb2422->CFG2.bit.COMPOUND = 0; // compound device
218 pusb2422->CFG3.bit.STRING_EN = 1; // strings enabled
219 // pusb2422->NRD.bit.PORT2_NR = 0; // MCU is non-removable
220 pusb2422->MAXPB.reg = 20; // 0mA
221 pusb2422->HCMCB.reg = 20; // 0mA
222 pusb2422->MFRSL.reg = sizeof(MFRNAME) / sizeof(uint16_t);
223 pusb2422->PRDSL.reg = sizeof(PRDNAME) / sizeof(uint16_t);
224 pusb2422->SERSL.reg = serial_length;
225 memcpy(pusb2422->MFRSTR, MFRNAME, sizeof(MFRNAME));
226 memcpy(pusb2422->PRDSTR, PRDNAME, sizeof(PRDNAME));
227 memcpy(pusb2422->SERSTR, serial_use, serial_length * sizeof(uint16_t));
228 // pusb2422->BOOSTUP.bit.BOOST=3; //upstream port
229 // pusb2422->BOOSTDOWN.bit.BOOST1=0; // extra port
230 // pusb2422->BOOSTDOWN.bit.BOOST2=2; //MCU is close
231 pusb2422->STCD.bit.USB_ATTACH = 1;
232 USB_write2422_block();
233 147
234 adc_extra = 0; 148 adc_extra = 0;
235 149
236 DBGC(DC_USB_CONFIGURE_COMPLETE); 150 DBGC(DC_USB_CONFIGURE_COMPLETE);
237} 151}
238 152
239uint16_t USB_active(void) { return (PORT->Group[USB2422_HUB_ACTIVE_GROUP].IN.reg & (1 << USB2422_HUB_ACTIVE_PIN)) != 0; } 153uint16_t USB_active(void) { return USB2422_active(); }
240 154
241void USB_set_host_by_voltage(void) { 155void USB_set_host_by_voltage(void) {
242 // UP is upstream device (HOST) 156 // UP is upstream device (HOST)
@@ -314,7 +228,7 @@ void USB_set_host_by_voltage(void) {
314 DBGC(DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE); 228 DBGC(DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE);
315} 229}
316 230
317uint8_t USB2422_Port_Detect_Init(void) { 231uint8_t USB_Hub_Port_Detect_Init(void) {
318 uint32_t port_detect_retry_ms; 232 uint32_t port_detect_retry_ms;
319 uint32_t tmod; 233 uint32_t tmod;
320 234
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_hub.h b/tmk_core/protocol/arm_atsam/usb/usb_hub.h
new file mode 100644
index 000000000..76b1e0a32
--- /dev/null
+++ b/tmk_core/protocol/arm_atsam/usb/usb_hub.h
@@ -0,0 +1,51 @@
1/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef _USB2422_H_
19#define _USB2422_H_
20
21#define REV_USB2422 0x100
22
23#define PORT_DETECT_RETRY_INTERVAL 2000
24
25#define USB_EXTRA_ADC_THRESHOLD 900
26
27#define USB_EXTRA_STATE_DISABLED 0
28#define USB_EXTRA_STATE_ENABLED 1
29#define USB_EXTRA_STATE_UNKNOWN 2
30#define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3
31
32#define USB_HOST_PORT_1 0
33#define USB_HOST_PORT_2 1
34#define USB_HOST_PORT_UNKNOWN 2
35
36extern uint8_t usb_host_port;
37extern uint8_t usb_extra_state;
38extern uint8_t usb_extra_manual;
39extern uint8_t usb_gcr_auto;
40
41void USB_Hub_init(void);
42uint8_t USB_Hub_Port_Detect_Init(void);
43void USB_reset(void);
44void USB_configure(void);
45uint16_t USB_active(void);
46void USB_set_host_by_voltage(void);
47uint16_t adc_get(uint8_t muxpos);
48void USB_HandleExtraDevice(void);
49void USB_ExtraSetState(uint8_t state);
50
51#endif //_USB2422_H_