@@ -20,6 +20,7 @@ LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
20
20
#include "reg/reg_acpi.h"
21
21
#include "reg/reg_emi.h"
22
22
#include "reg/reg_espi.h"
23
+ #include "reg/reg_kbc.h"
23
24
#include "reg/reg_port80.h"
24
25
25
26
BUILD_ASSERT (DT_NUM_INST_STATUS_OKAY (DT_DRV_COMPAT ) == 1 , "support only one espi compatible node" );
@@ -28,6 +29,11 @@ struct espi_rts5912_config {
28
29
volatile struct espi_reg * const espi_reg ;
29
30
uint32_t espislv_clk_grp ;
30
31
uint32_t espislv_clk_idx ;
32
+ #ifdef CONFIG_ESPI_PERIPHERAL_8042_KBC
33
+ volatile struct kbc_reg * const kbc_reg ;
34
+ uint32_t kbc_clk_grp ;
35
+ uint32_t kbc_clk_idx ;
36
+ #endif
31
37
#ifdef CONFIG_ESPI_PERIPHERAL_HOST_IO
32
38
volatile struct acpi_reg * const acpi_reg ;
33
39
uint32_t acpi_clk_grp ;
@@ -58,6 +64,10 @@ struct espi_rts5912_config {
58
64
struct espi_rts5912_data {
59
65
sys_slist_t callbacks ;
60
66
uint32_t config_data ;
67
+ #ifdef CONFIG_ESPI_PERIPHERAL_8042_KBC
68
+ int kbc_int_en ;
69
+ int kbc_pre_irq1 ;
70
+ #endif
61
71
#ifdef CONFIG_ESPI_OOB_CHANNEL
62
72
struct k_sem oob_rx_lock ;
63
73
struct k_sem oob_tx_lock ;
@@ -71,6 +81,222 @@ struct espi_rts5912_data {
71
81
#endif
72
82
};
73
83
84
+ /*
85
+ * =========================================================================
86
+ * ESPI Peripheral KBC
87
+ * =========================================================================
88
+ */
89
+
90
+ #ifdef CONFIG_ESPI_PERIPHERAL_8042_KBC
91
+
92
+ static int espi_send_vw_event (uint8_t index , uint8_t data , const struct device * dev );
93
+
94
+ static void kbc_ibf_isr (const struct device * dev )
95
+ {
96
+ const struct espi_rts5912_config * const espi_config = dev -> config ;
97
+ struct espi_rts5912_data * espi_data = dev -> data ;
98
+ struct espi_event evt = {
99
+ ESPI_BUS_PERIPHERAL_NOTIFICATION ,
100
+ ESPI_PERIPHERAL_8042_KBC ,
101
+ ESPI_PERIPHERAL_NODATA ,
102
+ };
103
+ volatile struct kbc_reg * const kbc_reg = espi_config -> kbc_reg ;
104
+ struct espi_evt_data_kbc * kbc_evt = (struct espi_evt_data_kbc * )& evt .evt_data ;
105
+
106
+ /*
107
+ * Indicates if the host sent a command or data.
108
+ * 0 = data
109
+ * 1 = Command.
110
+ */
111
+ kbc_evt -> type = kbc_reg -> STS & KBC_STS_CMDSEL ? 1 : 0 ;
112
+
113
+ /* The data in KBC Input Buffer */
114
+ kbc_evt -> data = kbc_reg -> IB ;
115
+
116
+ /* KBC Input Buffer Full event */
117
+ kbc_evt -> evt = HOST_KBC_EVT_IBF ;
118
+ espi_send_callbacks (& espi_data -> callbacks , dev , evt );
119
+ }
120
+
121
+ static void kbc_obe_isr (const struct device * dev )
122
+ {
123
+ const struct espi_rts5912_config * const espi_config = dev -> config ;
124
+ struct espi_rts5912_data * espi_data = dev -> data ;
125
+ struct espi_event evt = {
126
+ ESPI_BUS_PERIPHERAL_NOTIFICATION ,
127
+ ESPI_PERIPHERAL_8042_KBC ,
128
+ ESPI_PERIPHERAL_NODATA ,
129
+ };
130
+ volatile struct kbc_reg * const kbc_reg = espi_config -> kbc_reg ;
131
+ struct espi_evt_data_kbc * kbc_evt = (struct espi_evt_data_kbc * )& evt .evt_data ;
132
+
133
+ if (espi_data -> kbc_pre_irq1 == 1 && !espi_send_vw_event (0x0 , 0x01 , dev )) {
134
+ espi_data -> kbc_pre_irq1 = 0 ;
135
+ }
136
+
137
+ if (kbc_reg -> STS & KBC_STS_OBF ) {
138
+ kbc_reg -> OB |= KBC_OB_OBCLR ;
139
+ }
140
+
141
+ /* Notify application that host already read out data. */
142
+ kbc_evt -> type = 0 ;
143
+ kbc_evt -> data = 0 ;
144
+ kbc_evt -> evt = HOST_KBC_EVT_OBE ;
145
+ espi_send_callbacks (& espi_data -> callbacks , dev , evt );
146
+ }
147
+
148
+ static int espi_kbc_setup (const struct device * dev )
149
+ {
150
+ const struct espi_rts5912_config * const espi_config = dev -> config ;
151
+ struct espi_rts5912_data * const espi_data = dev -> data ;
152
+ struct rts5912_sccon_subsys sccon ;
153
+ volatile struct kbc_reg * const kbc_reg = espi_config -> kbc_reg ;
154
+ int rc ;
155
+
156
+ if (!device_is_ready (espi_config -> clk_dev )) {
157
+ LOG_ERR ("KBC clock not ready" );
158
+ return - ENODEV ;
159
+ }
160
+
161
+ espi_data -> kbc_int_en = 1 ;
162
+ espi_data -> kbc_pre_irq1 = 0 ;
163
+
164
+ sccon .clk_grp = espi_config -> kbc_clk_grp ;
165
+ sccon .clk_idx = espi_config -> kbc_clk_idx ;
166
+
167
+ rc = clock_control_on (espi_config -> clk_dev , (clock_control_subsys_t )& sccon );
168
+ if (rc != 0 ) {
169
+ LOG_ERR ("KBC clock control on failed" );
170
+ return rc ;
171
+ }
172
+
173
+ kbc_reg -> VWCTRL1 = (0x01 << KBC_VWCTRL1_IRQNUM_Pos ) | KBC_VWCTRL1_ACTEN ;
174
+ kbc_reg -> INTEN = KBC_INTEN_IBFINTEN | KBC_INTEN_OBFINTEN ;
175
+
176
+ NVIC_ClearPendingIRQ (DT_IRQ_BY_NAME (DT_DRV_INST (0 ), kbc_ibf , irq ));
177
+ NVIC_ClearPendingIRQ (DT_IRQ_BY_NAME (DT_DRV_INST (0 ), kbc_obe , irq ));
178
+
179
+ /* IBF */
180
+ IRQ_CONNECT (DT_IRQ_BY_NAME (DT_DRV_INST (0 ), kbc_ibf , irq ),
181
+ DT_IRQ_BY_NAME (DT_DRV_INST (0 ), kbc_ibf , priority ), kbc_ibf_isr ,
182
+ DEVICE_DT_GET (DT_DRV_INST (0 )), 0 );
183
+ irq_enable (DT_IRQ_BY_NAME (DT_DRV_INST (0 ), kbc_ibf , irq ));
184
+
185
+ /* OBE */
186
+ IRQ_CONNECT (DT_IRQ_BY_NAME (DT_DRV_INST (0 ), kbc_obe , irq ),
187
+ DT_IRQ_BY_NAME (DT_DRV_INST (0 ), kbc_obe , priority ), kbc_obe_isr ,
188
+ DEVICE_DT_GET (DT_DRV_INST (0 )), 0 );
189
+ irq_enable (DT_IRQ_BY_NAME (DT_DRV_INST (0 ), kbc_obe , irq ));
190
+
191
+ return 0 ;
192
+ }
193
+
194
+ static int lpc_request_read_8042 (const struct device * dev , enum lpc_peripheral_opcode op ,
195
+ uint32_t * data )
196
+ {
197
+ const struct espi_rts5912_config * const espi_config = dev -> config ;
198
+ volatile struct kbc_reg * const kbc_reg = espi_config -> kbc_reg ;
199
+
200
+ switch (op ) {
201
+ case E8042_OBF_HAS_CHAR :
202
+ * data = (kbc_reg -> STS & KBC_STS_OBF ) ? 1 : 0 ;
203
+ break ;
204
+ case E8042_IBF_HAS_CHAR :
205
+ * data = (kbc_reg -> STS & KBC_STS_IBF ) ? 1 : 0 ;
206
+ break ;
207
+ case E8042_READ_KB_STS :
208
+ * data = kbc_reg -> STS ;
209
+ break ;
210
+ default :
211
+ return - EINVAL ;
212
+ }
213
+
214
+ return 0 ;
215
+ }
216
+
217
+ static int espi_send_vw_event (uint8_t index , uint8_t data , const struct device * dev );
218
+
219
+ static void espi_send_vw_event_with_kbdata (uint8_t index , uint8_t data , uint32_t kbc_data ,
220
+ const struct device * dev );
221
+
222
+ static uint8_t kbc_write (uint8_t data , const struct device * dev )
223
+ {
224
+ const struct espi_rts5912_config * const espi_config = dev -> config ;
225
+ const struct espi_rts5912_data * const espi_data = dev -> data ;
226
+ volatile struct kbc_reg * const kbc_reg = espi_config -> kbc_reg ;
227
+ uint32_t exData = (uint32_t )data ;
228
+
229
+ if (espi_data -> kbc_pre_irq1 == 1 ) {
230
+ /* Gen IRQ1-Level High to VW ch */
231
+ espi_send_vw_event (0x0 , 0x01 , dev );
232
+ }
233
+
234
+ if (espi_data -> kbc_int_en ) {
235
+ /* Gen IRQ1-Level High to VW ch */
236
+ espi_send_vw_event_with_kbdata (0x0 , 0x81 , exData , dev );
237
+ } else {
238
+ kbc_reg -> OB = exData ;
239
+ }
240
+
241
+ return 0 ;
242
+ }
243
+
244
+ static int lpc_request_write_8042 (const struct device * dev , enum lpc_peripheral_opcode op ,
245
+ uint32_t * data )
246
+ {
247
+ struct espi_rts5912_data * const espi_data = dev -> data ;
248
+ const struct espi_rts5912_config * const espi_config = dev -> config ;
249
+ volatile struct kbc_reg * const kbc_reg = espi_config -> kbc_reg ;
250
+
251
+ switch (op ) {
252
+ case E8042_WRITE_KB_CHAR :
253
+ kbc_write (* data & 0xff , dev );
254
+ break ;
255
+ case E8042_WRITE_MB_CHAR :
256
+ kbc_write (* data & 0xff , dev );
257
+ break ;
258
+ case E8042_RESUME_IRQ :
259
+ espi_data -> kbc_int_en = 1 ;
260
+ break ;
261
+ case E8042_PAUSE_IRQ :
262
+ espi_data -> kbc_int_en = 0 ;
263
+ break ;
264
+ case E8042_CLEAR_OBF :
265
+ kbc_reg -> OB |= KBC_OB_OBCLR ;
266
+ break ;
267
+ case E8042_SET_FLAG :
268
+ /* FW shouldn't modify these flags directly */
269
+ * data &= ~(KBC_STS_OBF | KBC_STS_IBF | KBC_STS_STS2 );
270
+ kbc_reg -> STS |= * data & 0xff ;
271
+ break ;
272
+ case E8042_CLEAR_FLAG :
273
+ /* FW shouldn't modify these flags directly */
274
+ * data |= KBC_STS_OBF | KBC_STS_IBF | KBC_STS_STS2 ;
275
+ kbc_reg -> STS &= ~(* data & 0xff );
276
+ break ;
277
+ default :
278
+ return - EINVAL ;
279
+ }
280
+
281
+ return 0 ;
282
+ }
283
+
284
+ #else /* CONFIG_ESPI_PERIPHERAL_8042_KBC */
285
+
286
+ static int lpc_request_read_8042 (const struct device * dev , enum lpc_peripheral_opcode op ,
287
+ uint32_t * data )
288
+ {
289
+ return - ENOTSUP ;
290
+ }
291
+
292
+ static int lpc_request_write_8042 (const struct device * dev , enum lpc_peripheral_opcode op ,
293
+ uint32_t * data )
294
+ {
295
+ return - ENOTSUP ;
296
+ }
297
+
298
+ #endif /* CONFIG_ESPI_PERIPHERAL_8042_KBC */
299
+
74
300
/*
75
301
* =========================================================================
76
302
* ESPI Peripheral Shared Memory Region
@@ -1238,6 +1464,81 @@ static void espi_vw_ch_setup(const struct device *dev)
1238
1464
irq_enable (DT_IRQ_BY_NAME (DT_DRV_INST (0 ), vw_idx61 , irq ));
1239
1465
}
1240
1466
1467
+ #ifdef CONFIG_ESPI_PERIPHERAL_8042_KBC
1468
+
1469
+ #define ESPI_VW_EVENT_IDLE_TIMEOUT_US 1024UL
1470
+ #define ESPI_VW_EVENT_COMPLETE_TIMEOUT_US 10000UL
1471
+
1472
+ static int espi_send_vw_event (uint8_t index , uint8_t data , const struct device * dev )
1473
+ {
1474
+ const struct espi_rts5912_config * const espi_config = dev -> config ;
1475
+ uint32_t i ;
1476
+
1477
+ volatile struct espi_reg * const espi_reg = espi_config -> espi_reg ;
1478
+
1479
+ if ((espi_reg -> EVCFG & ESPI_EVCFG_CHEN ) == 0 || (espi_reg -> EVCFG & ESPI_EVCFG_CHRDY ) == 0 ) {
1480
+ return - EBUSY ;
1481
+ }
1482
+
1483
+ /* Wait for TX FIFO to not be full before writing, with timeout */
1484
+ if (!WAIT_FOR (!(espi_reg -> EVSTS & ESPI_EVSTS_TXFULL ), ESPI_VW_EVENT_IDLE_TIMEOUT_US ,
1485
+ k_busy_wait (1 ))) {
1486
+ return - EBUSY ;
1487
+ }
1488
+
1489
+ i = 0x0000FFFF & ((uint32_t )index << 8 | (uint32_t )data );
1490
+ espi_reg -> EVTXDAT = i ;
1491
+
1492
+ /* Wait for TX FIFO to not be full after writing, with shorter timeout */
1493
+ if (!WAIT_FOR (!(espi_reg -> EVSTS & ESPI_EVSTS_TXFULL ), ESPI_VW_EVENT_COMPLETE_TIMEOUT_US ,
1494
+ NULL )) {
1495
+ return - EBUSY ;
1496
+ }
1497
+
1498
+ espi_reg -> EVSTS |= ESPI_EVSTS_TXDONE ;
1499
+
1500
+ return 0 ;
1501
+ }
1502
+
1503
+ static void espi_send_vw_event_with_kbdata (uint8_t index , uint8_t data , uint32_t kbc_data ,
1504
+ const struct device * dev )
1505
+ {
1506
+ const struct espi_rts5912_config * const espi_config = dev -> config ;
1507
+ struct espi_rts5912_data * const espi_data = dev -> data ;
1508
+ volatile struct espi_reg * const espi_reg = espi_config -> espi_reg ;
1509
+ volatile struct kbc_reg * const kbc_reg = espi_config -> kbc_reg ;
1510
+ uint32_t i ;
1511
+
1512
+ if ((espi_reg -> EVCFG & ESPI_EVCFG_CHEN ) == 0 || (espi_reg -> EVCFG & ESPI_EVCFG_CHRDY ) == 0 ) {
1513
+ return ;
1514
+ }
1515
+
1516
+ /* Wait for TX FIFO to not be full before writing, with timeout */
1517
+ if (!WAIT_FOR (!(espi_reg -> EVSTS & ESPI_EVSTS_TXFULL ), ESPI_VW_EVENT_COMPLETE_TIMEOUT_US ,
1518
+ k_busy_wait (1 ))) {
1519
+ return ;
1520
+ }
1521
+
1522
+ __disable_irq ();
1523
+ kbc_reg -> OB = kbc_data ;
1524
+ i = 0x0000FFFF & ((uint32_t )index << 8 | (uint32_t )data );
1525
+ espi_reg -> EVTXDAT = i ;
1526
+
1527
+ /* Wait for TX FIFO to not be full after writing, in IRQ disabled state */
1528
+ if (!WAIT_FOR (!(espi_reg -> EVSTS & ESPI_EVSTS_TXFULL ), ESPI_VW_EVENT_COMPLETE_TIMEOUT_US ,
1529
+ k_busy_wait (1 ))) {
1530
+ espi_data -> kbc_pre_irq1 = 1 ;
1531
+ __enable_irq ();
1532
+ return ;
1533
+ }
1534
+
1535
+ espi_data -> kbc_pre_irq1 = 1 ;
1536
+ espi_reg -> EVSTS |= ESPI_EVSTS_TXDONE ;
1537
+ __enable_irq ();
1538
+ }
1539
+
1540
+ #endif /* CONFIG_ESPI_PERIPHERAL_8042_KBC */
1541
+
1241
1542
#endif /* CONFIG_ESPI_VWIRE_CHANNEL */
1242
1543
1243
1544
/*
@@ -1883,6 +2184,15 @@ static int espi_rts5912_init(const struct device *dev)
1883
2184
/* Setup eSPI bus reset */
1884
2185
espi_bus_reset_setup (dev );
1885
2186
2187
+ #ifdef CONFIG_ESPI_PERIPHERAL_8042_KBC
2188
+ /* Setup KBC */
2189
+ rc = espi_kbc_setup (dev );
2190
+ if (rc != 0 ) {
2191
+ LOG_ERR ("eSPI KBC setup failed" );
2192
+ goto exit ;
2193
+ }
2194
+ #endif
2195
+
1886
2196
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
1887
2197
espi_setup_acpi_shm (espi_config );
1888
2198
#endif
@@ -1950,6 +2260,11 @@ static const struct espi_rts5912_config espi_rts5912_config = {
1950
2260
.espi_reg = (volatile struct espi_reg * const )DT_INST_REG_ADDR_BY_NAME (0 , espi_target ),
1951
2261
.espislv_clk_grp = DT_CLOCKS_CELL_BY_NAME (DT_DRV_INST (0 ), espi_target , clk_grp ),
1952
2262
.espislv_clk_idx = DT_CLOCKS_CELL_BY_NAME (DT_DRV_INST (0 ), espi_target , clk_idx ),
2263
+ #ifdef CONFIG_ESPI_PERIPHERAL_8042_KBC
2264
+ .kbc_reg = (volatile struct kbc_reg * const )DT_INST_REG_ADDR_BY_NAME (0 , kbc ),
2265
+ .kbc_clk_grp = DT_CLOCKS_CELL_BY_NAME (DT_DRV_INST (0 ), kbc , clk_grp ),
2266
+ .kbc_clk_idx = DT_CLOCKS_CELL_BY_NAME (DT_DRV_INST (0 ), kbc , clk_idx ),
2267
+ #endif
1953
2268
#ifdef CONFIG_ESPI_PERIPHERAL_HOST_IO
1954
2269
.acpi_reg = (volatile struct acpi_reg * const )DT_INST_REG_ADDR_BY_NAME (0 , acpi ),
1955
2270
.acpi_clk_grp = DT_CLOCKS_CELL_BY_NAME (DT_DRV_INST (0 ), acpi , clk_grp ),
0 commit comments