driver: espi: add espi vw channel driver for rts5912
add espi vw channel driver for rts5912 Signed-off-by: jhan bo chao <jhan_bo_chao@realtek.com>
This commit is contained in:
parent
9d41eac7ac
commit
1c461e38ca
1 changed files with 912 additions and 0 deletions
|
@ -45,6 +45,891 @@ struct espi_rts5912_data {
|
|||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* ESPI VWIRE channel
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ESPI_VWIRE_CHANNEL
|
||||
|
||||
#define VW_CH_IDX2 0x02UL
|
||||
#define VW_CH_IDX3 0x03UL
|
||||
#define VW_CH_IDX4 0x04UL
|
||||
#define VW_CH_IDX5 0x05UL
|
||||
#define VW_CH_IDX6 0x06UL
|
||||
#define VW_CH_IDX7 0x07UL
|
||||
#define VW_CH_IDX40 0x40UL
|
||||
#define VW_CH_IDX41 0x41UL
|
||||
#define VW_CH_IDX42 0x42UL
|
||||
#define VW_CH_IDX43 0x43UL
|
||||
#define VW_CH_IDX44 0x44UL
|
||||
#define VW_CH_IDX47 0x47UL
|
||||
#define VW_CH_IDX4A 0x4AUL
|
||||
#define VW_CH_IDX51 0x51UL
|
||||
#define VW_CH_IDX61 0x61UL
|
||||
|
||||
struct espi_vw_channel {
|
||||
uint8_t vw_index;
|
||||
uint8_t level_mask;
|
||||
uint8_t valid_mask;
|
||||
};
|
||||
|
||||
struct espi_vw_signal_t {
|
||||
enum espi_vwire_signal signal;
|
||||
void (*vw_signal_callback)(const struct device *dev);
|
||||
};
|
||||
|
||||
#define VW_CH(signal, index, level, valid) \
|
||||
[signal] = {.vw_index = index, .level_mask = level, .valid_mask = valid}
|
||||
|
||||
static const struct espi_vw_channel vw_channel_list[] = {
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SLP_S3, VW_CH_IDX2, BIT(0), BIT(4)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SLP_S4, VW_CH_IDX2, BIT(1), BIT(5)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SLP_S5, VW_CH_IDX2, BIT(2), BIT(6)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_OOB_RST_WARN, VW_CH_IDX3, BIT(2), BIT(6)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_PLTRST, VW_CH_IDX3, BIT(1), BIT(5)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SUS_STAT, VW_CH_IDX3, BIT(0), BIT(4)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_NMIOUT, VW_CH_IDX7, BIT(2), BIT(6)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SMIOUT, VW_CH_IDX7, BIT(1), BIT(5)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_HOST_RST_WARN, VW_CH_IDX7, BIT(0), BIT(4)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SLP_A, VW_CH_IDX41, BIT(3), BIT(7)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SUS_PWRDN_ACK, VW_CH_IDX41, BIT(1), BIT(5)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SUS_WARN, VW_CH_IDX41, BIT(0), BIT(4)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SLP_WLAN, VW_CH_IDX42, BIT(1), BIT(5)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SLP_LAN, VW_CH_IDX42, BIT(0), BIT(4)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_HOST_C10, VW_CH_IDX47, BIT(0), BIT(4)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_DNX_WARN, VW_CH_IDX4A, BIT(1), BIT(5)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_PME, VW_CH_IDX4, BIT(3), BIT(7)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_WAKE, VW_CH_IDX4, BIT(2), BIT(6)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_OOB_RST_ACK, VW_CH_IDX4, BIT(0), BIT(4)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_TARGET_BOOT_STS, VW_CH_IDX5, BIT(3), BIT(7)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_ERR_NON_FATAL, VW_CH_IDX5, BIT(2), BIT(6)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_ERR_FATAL, VW_CH_IDX5, BIT(1), BIT(5)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_TARGET_BOOT_DONE, VW_CH_IDX5, BIT(0), BIT(4)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_HOST_RST_ACK, VW_CH_IDX6, BIT(3), BIT(7)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_RST_CPU_INIT, VW_CH_IDX6, BIT(2), BIT(6)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SMI, VW_CH_IDX6, BIT(1), BIT(5)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SCI, VW_CH_IDX6, BIT(0), BIT(4)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_DNX_ACK, VW_CH_IDX40, BIT(1), BIT(5)),
|
||||
VW_CH(ESPI_VWIRE_SIGNAL_SUS_ACK, VW_CH_IDX40, BIT(0), BIT(4)),
|
||||
};
|
||||
|
||||
struct espi_vw_ch_cached {
|
||||
uint8_t idx2;
|
||||
uint8_t idx3;
|
||||
uint8_t idx7;
|
||||
uint8_t idx41;
|
||||
uint8_t idx42;
|
||||
uint8_t idx43;
|
||||
uint8_t idx44;
|
||||
uint8_t idx47;
|
||||
uint8_t idx4a;
|
||||
uint8_t idx51;
|
||||
uint8_t idx61;
|
||||
};
|
||||
|
||||
struct espi_vw_tx_cached {
|
||||
uint8_t idx4;
|
||||
uint8_t idx5;
|
||||
uint8_t idx6;
|
||||
uint8_t idx40;
|
||||
};
|
||||
|
||||
static struct espi_vw_ch_cached espi_vw_ch_cached_data;
|
||||
static struct espi_vw_tx_cached espi_vw_tx_cached_data;
|
||||
|
||||
static int espi_rts5912_send_vwire(const struct device *dev, enum espi_vwire_signal signal,
|
||||
uint8_t level);
|
||||
static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_signal signal,
|
||||
uint8_t *level);
|
||||
static int vw_signal_set_valid(const struct device *dev, enum espi_vwire_signal signal,
|
||||
uint8_t valid);
|
||||
static void notify_system_state(const struct device *dev, enum espi_vwire_signal signal);
|
||||
static void notify_host_warning(const struct device *dev, enum espi_vwire_signal signal);
|
||||
static void vw_slp3_handler(const struct device *dev);
|
||||
static void vw_slp4_handler(const struct device *dev);
|
||||
static void vw_slp5_handler(const struct device *dev);
|
||||
static void vw_sus_stat_handler(const struct device *dev);
|
||||
static void vw_pltrst_handler(const struct device *dev);
|
||||
static void vw_oob_rst_warn_handler(const struct device *dev);
|
||||
static void vw_host_rst_warn_handler(const struct device *dev);
|
||||
static void vw_smiout_handler(const struct device *dev);
|
||||
static void vw_nmiout_handler(const struct device *dev);
|
||||
static void vw_sus_warn_handler(const struct device *dev);
|
||||
static void vw_sus_pwrdn_ack_handler(const struct device *dev);
|
||||
static void vw_sus_slp_a_handler(const struct device *dev);
|
||||
static void vw_slp_lan_handler(const struct device *dev);
|
||||
static void vw_slp_wlan_handler(const struct device *dev);
|
||||
static void vw_host_c10_handler(const struct device *dev);
|
||||
static void espi_vw_ch_setup(const struct device *dev);
|
||||
static void espi_vw_ch_isr(const struct device *dev);
|
||||
#ifdef CONFIG_ESPI_AUTOMATIC_BOOT_DONE_ACKNOWLEDGE
|
||||
static void send_target_bootdone(const struct device *dev);
|
||||
#endif
|
||||
|
||||
static void espi_vw_ch_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
struct espi_rts5912_data *data = dev->data;
|
||||
|
||||
struct espi_event evt = {.evt_type = ESPI_BUS_EVENT_CHANNEL_READY,
|
||||
.evt_details = ESPI_CHANNEL_VWIRE,
|
||||
.evt_data = 0};
|
||||
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
|
||||
uint32_t config = espi_reg->EVCFG;
|
||||
|
||||
evt.evt_data = (config & ESPI_EVCFG_CHEN) ? 1 : 0;
|
||||
espi_send_callbacks(&data->callbacks, dev, evt);
|
||||
|
||||
if (config & ESPI_EVCFG_CHEN) {
|
||||
vw_signal_set_valid(dev, ESPI_VWIRE_SIGNAL_TARGET_BOOT_STS, 1);
|
||||
vw_signal_set_valid(dev, ESPI_VWIRE_SIGNAL_TARGET_BOOT_DONE, 1);
|
||||
|
||||
#ifdef CONFIG_ESPI_AUTOMATIC_BOOT_DONE_ACKNOWLEDGE
|
||||
send_target_bootdone(dev);
|
||||
#endif
|
||||
}
|
||||
espi_reg->EVSTS = ESPI_EVSTS_RXIDXCHG;
|
||||
}
|
||||
|
||||
static const struct espi_vw_signal_t vw_idx2_signals[] = {
|
||||
{ESPI_VWIRE_SIGNAL_SLP_S3, vw_slp3_handler},
|
||||
{ESPI_VWIRE_SIGNAL_SLP_S4, vw_slp4_handler},
|
||||
{ESPI_VWIRE_SIGNAL_SLP_S5, vw_slp5_handler},
|
||||
};
|
||||
|
||||
static void espi_vw_idx2_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
uint8_t cur_idx_data = espi_reg->EVIDX2;
|
||||
uint8_t updated_bit = cur_idx_data ^ espi_vw_ch_cached_data.idx2;
|
||||
|
||||
if (espi_reg->EVSTS & ESPI_EVSTS_IDX2CHG) {
|
||||
espi_vw_ch_cached_data.idx2 = cur_idx_data;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(vw_idx2_signals); i++) {
|
||||
enum espi_vwire_signal vw_signal = vw_idx2_signals[i].signal;
|
||||
|
||||
if (updated_bit & vw_channel_list[vw_signal].level_mask &&
|
||||
vw_idx2_signals[i].vw_signal_callback != NULL) {
|
||||
vw_idx2_signals[i].vw_signal_callback(dev);
|
||||
}
|
||||
}
|
||||
if (espi_vw_ch_cached_data.idx2 == espi_reg->EVIDX2) {
|
||||
espi_reg->EVSTS = ESPI_EVSTS_IDX2CHG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct espi_vw_signal_t vw_idx3_signals[] = {
|
||||
{ESPI_VWIRE_SIGNAL_SUS_STAT, vw_sus_stat_handler},
|
||||
{ESPI_VWIRE_SIGNAL_PLTRST, vw_pltrst_handler},
|
||||
{ESPI_VWIRE_SIGNAL_OOB_RST_WARN, vw_oob_rst_warn_handler},
|
||||
};
|
||||
|
||||
static void espi_vw_idx3_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
uint8_t cur_idx_data = espi_reg->EVIDX3;
|
||||
uint8_t updated_bit = cur_idx_data ^ espi_vw_ch_cached_data.idx3;
|
||||
|
||||
if (espi_reg->EVSTS & ESPI_EVSTS_IDX3CHG) {
|
||||
espi_vw_ch_cached_data.idx3 = cur_idx_data;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(vw_idx3_signals); i++) {
|
||||
enum espi_vwire_signal vw_signal = vw_idx3_signals[i].signal;
|
||||
|
||||
if (updated_bit & vw_channel_list[vw_signal].level_mask &&
|
||||
vw_idx3_signals[i].vw_signal_callback != NULL) {
|
||||
vw_idx3_signals[i].vw_signal_callback(dev);
|
||||
}
|
||||
}
|
||||
if (espi_vw_ch_cached_data.idx3 == espi_reg->EVIDX3) {
|
||||
espi_reg->EVSTS = ESPI_EVSTS_IDX3CHG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct espi_vw_signal_t vw_idx7_signals[] = {
|
||||
{ESPI_VWIRE_SIGNAL_HOST_RST_WARN, vw_host_rst_warn_handler},
|
||||
{ESPI_VWIRE_SIGNAL_SMIOUT, vw_smiout_handler},
|
||||
{ESPI_VWIRE_SIGNAL_NMIOUT, vw_nmiout_handler},
|
||||
};
|
||||
|
||||
static void espi_vw_idx7_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
uint8_t cur_idx_data = espi_reg->EVIDX7;
|
||||
uint8_t updated_bit = cur_idx_data ^ espi_vw_ch_cached_data.idx7;
|
||||
|
||||
if (espi_reg->EVSTS & ESPI_EVSTS_IDX7CHG) {
|
||||
espi_vw_ch_cached_data.idx7 = cur_idx_data;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(vw_idx7_signals); i++) {
|
||||
enum espi_vwire_signal vw_signal = vw_idx7_signals[i].signal;
|
||||
|
||||
if (updated_bit & vw_channel_list[vw_signal].level_mask &&
|
||||
vw_idx7_signals[i].vw_signal_callback != NULL) {
|
||||
vw_idx7_signals[i].vw_signal_callback(dev);
|
||||
}
|
||||
}
|
||||
if (espi_vw_ch_cached_data.idx7 == espi_reg->EVIDX7) {
|
||||
espi_reg->EVSTS = ESPI_EVSTS_IDX7CHG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct espi_vw_signal_t vw_idx41_signals[] = {
|
||||
{ESPI_VWIRE_SIGNAL_SUS_WARN, vw_sus_warn_handler},
|
||||
{ESPI_VWIRE_SIGNAL_SUS_PWRDN_ACK, vw_sus_pwrdn_ack_handler},
|
||||
{ESPI_VWIRE_SIGNAL_SLP_A, vw_sus_slp_a_handler},
|
||||
};
|
||||
|
||||
static void espi_vw_idx41_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
uint8_t cur_idx_data = espi_reg->EVIDX41;
|
||||
uint8_t updated_bit = cur_idx_data ^ espi_vw_ch_cached_data.idx41;
|
||||
|
||||
if (espi_reg->EVSTS & ESPI_EVSTS_IDX41CHG) {
|
||||
espi_vw_ch_cached_data.idx41 = cur_idx_data;
|
||||
for (int i = 0; i < ARRAY_SIZE(vw_idx41_signals); i++) {
|
||||
enum espi_vwire_signal vw_signal = vw_idx41_signals[i].signal;
|
||||
|
||||
if (updated_bit & vw_channel_list[vw_signal].level_mask &&
|
||||
vw_idx41_signals[i].vw_signal_callback != NULL) {
|
||||
vw_idx41_signals[i].vw_signal_callback(dev);
|
||||
}
|
||||
}
|
||||
if (espi_vw_ch_cached_data.idx41 == espi_reg->EVIDX41) {
|
||||
espi_reg->EVSTS = ESPI_EVSTS_IDX41CHG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct espi_vw_signal_t vw_idx42_signals[] = {
|
||||
{ESPI_VWIRE_SIGNAL_SLP_LAN, vw_slp_lan_handler},
|
||||
{ESPI_VWIRE_SIGNAL_SLP_WLAN, vw_slp_wlan_handler},
|
||||
};
|
||||
|
||||
static void espi_vw_idx42_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
uint8_t cur_idx_data = espi_reg->EVIDX42;
|
||||
uint8_t updated_bit = cur_idx_data ^ espi_vw_ch_cached_data.idx42;
|
||||
|
||||
if (espi_reg->EVSTS & ESPI_EVSTS_IDX42CHG) {
|
||||
espi_vw_ch_cached_data.idx42 = cur_idx_data;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(vw_idx42_signals); i++) {
|
||||
enum espi_vwire_signal vw_signal = vw_idx42_signals[i].signal;
|
||||
|
||||
if (updated_bit & vw_channel_list[vw_signal].level_mask &&
|
||||
vw_idx42_signals[i].vw_signal_callback != NULL) {
|
||||
vw_idx42_signals[i].vw_signal_callback(dev);
|
||||
}
|
||||
}
|
||||
if (espi_vw_ch_cached_data.idx42 == espi_reg->EVIDX42) {
|
||||
espi_reg->EVSTS = ESPI_EVSTS_IDX42CHG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct espi_vw_signal_t vw_idx43_signals[] = {};
|
||||
|
||||
static void espi_vw_idx43_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
uint8_t cur_idx_data = espi_reg->EVIDX43;
|
||||
uint8_t updated_bit = cur_idx_data ^ espi_vw_ch_cached_data.idx43;
|
||||
|
||||
if (espi_reg->EVSTS & ESPI_EVSTS_IDX43CHG) {
|
||||
espi_vw_ch_cached_data.idx43 = cur_idx_data;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(vw_idx43_signals); i++) {
|
||||
enum espi_vwire_signal vw_signal = vw_idx43_signals[i].signal;
|
||||
|
||||
if (updated_bit & vw_channel_list[vw_signal].level_mask &&
|
||||
vw_idx43_signals[i].vw_signal_callback != NULL) {
|
||||
vw_idx43_signals[i].vw_signal_callback(dev);
|
||||
}
|
||||
}
|
||||
if (espi_vw_ch_cached_data.idx43 == espi_reg->EVIDX43) {
|
||||
espi_reg->EVSTS = ESPI_EVSTS_IDX43CHG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct espi_vw_signal_t vw_idx44_signals[] = {};
|
||||
|
||||
static void espi_vw_idx44_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
uint8_t cur_idx_data = espi_reg->EVIDX44;
|
||||
uint8_t updated_bit = cur_idx_data ^ espi_vw_ch_cached_data.idx44;
|
||||
|
||||
if (espi_reg->EVSTS & ESPI_EVSTS_IDX44CHG) {
|
||||
espi_vw_ch_cached_data.idx44 = cur_idx_data;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(vw_idx44_signals); i++) {
|
||||
enum espi_vwire_signal vw_signal = vw_idx44_signals[i].signal;
|
||||
|
||||
if (updated_bit & vw_channel_list[vw_signal].level_mask &&
|
||||
vw_idx44_signals[i].vw_signal_callback != NULL) {
|
||||
vw_idx44_signals[i].vw_signal_callback(dev);
|
||||
}
|
||||
}
|
||||
if (espi_vw_ch_cached_data.idx44 == espi_reg->EVIDX44) {
|
||||
espi_reg->EVSTS = ESPI_EVSTS_IDX44CHG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct espi_vw_signal_t vw_idx47_signals[] = {
|
||||
{ESPI_VWIRE_SIGNAL_HOST_C10, vw_host_c10_handler},
|
||||
};
|
||||
|
||||
static void espi_vw_idx47_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
uint8_t cur_idx_data = espi_reg->EVIDX47;
|
||||
uint8_t updated_bit = cur_idx_data ^ espi_vw_ch_cached_data.idx47;
|
||||
|
||||
if (espi_reg->EVSTS & ESPI_EVSTS_IDX47CHG) {
|
||||
espi_vw_ch_cached_data.idx47 = cur_idx_data;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(vw_idx47_signals); i++) {
|
||||
enum espi_vwire_signal vw_signal = vw_idx47_signals[i].signal;
|
||||
|
||||
if (updated_bit & vw_channel_list[vw_signal].level_mask &&
|
||||
vw_idx47_signals[i].vw_signal_callback != NULL) {
|
||||
vw_idx47_signals[i].vw_signal_callback(dev);
|
||||
}
|
||||
}
|
||||
if (espi_vw_ch_cached_data.idx47 == espi_reg->EVIDX47) {
|
||||
espi_reg->EVSTS = ESPI_EVSTS_IDX47CHG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void espi_vw_idx4a_isr(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
}
|
||||
|
||||
static void espi_vw_idx51_isr(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
}
|
||||
|
||||
static void espi_vw_idx61_isr(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
}
|
||||
|
||||
static int vw_signal_set_valid(const struct device *dev, enum espi_vwire_signal signal,
|
||||
uint8_t valid)
|
||||
{
|
||||
uint8_t vw_index = vw_channel_list[signal].vw_index;
|
||||
uint8_t valid_mask = vw_channel_list[signal].valid_mask;
|
||||
|
||||
if (signal > ARRAY_SIZE(vw_channel_list)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
switch (vw_index) {
|
||||
case VW_CH_IDX4:
|
||||
if (valid) {
|
||||
espi_vw_tx_cached_data.idx4 |= valid_mask;
|
||||
} else {
|
||||
espi_vw_tx_cached_data.idx4 &= ~valid_mask;
|
||||
}
|
||||
break;
|
||||
case VW_CH_IDX5:
|
||||
if (valid) {
|
||||
espi_vw_tx_cached_data.idx5 |= valid_mask;
|
||||
} else {
|
||||
espi_vw_tx_cached_data.idx5 &= ~valid_mask;
|
||||
}
|
||||
break;
|
||||
case VW_CH_IDX6:
|
||||
if (valid) {
|
||||
espi_vw_tx_cached_data.idx6 |= valid_mask;
|
||||
} else {
|
||||
espi_vw_tx_cached_data.idx6 &= ~valid_mask;
|
||||
}
|
||||
break;
|
||||
case VW_CH_IDX40:
|
||||
if (valid) {
|
||||
espi_vw_tx_cached_data.idx40 |= valid_mask;
|
||||
} else {
|
||||
espi_vw_tx_cached_data.idx40 &= ~valid_mask;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vw_ch_isr_wa_cb(struct k_work *work)
|
||||
{
|
||||
espi_vw_ch_isr(DEVICE_DT_GET(DT_DRV_INST(0)));
|
||||
}
|
||||
static K_WORK_DELAYABLE_DEFINE(vw_ch_isr_wa, vw_ch_isr_wa_cb);
|
||||
|
||||
#ifdef CONFIG_ESPI_AUTOMATIC_BOOT_DONE_ACKNOWLEDGE
|
||||
static void send_target_bootdone(const struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
uint8_t boot_done;
|
||||
|
||||
ret = espi_rts5912_receive_vwire(dev, ESPI_VWIRE_SIGNAL_TARGET_BOOT_DONE, &boot_done);
|
||||
if (!ret && !boot_done) {
|
||||
espi_rts5912_send_vwire(dev, ESPI_VWIRE_SIGNAL_TARGET_BOOT_STS, 1);
|
||||
espi_rts5912_send_vwire(dev, ESPI_VWIRE_SIGNAL_TARGET_BOOT_DONE, 1);
|
||||
k_work_cancel_delayable(&vw_ch_isr_wa);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void notify_system_state(const struct device *dev, enum espi_vwire_signal signal)
|
||||
{
|
||||
struct espi_rts5912_data *data = dev->data;
|
||||
struct espi_event evt = {ESPI_BUS_EVENT_VWIRE_RECEIVED, 0, 0};
|
||||
|
||||
uint8_t status = 0;
|
||||
|
||||
espi_rts5912_receive_vwire(dev, signal, &status);
|
||||
|
||||
evt.evt_details = signal;
|
||||
evt.evt_data = status;
|
||||
espi_send_callbacks(&data->callbacks, dev, evt);
|
||||
}
|
||||
|
||||
static void notify_host_warning(const struct device *dev, enum espi_vwire_signal signal)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
|
||||
espi_rts5912_receive_vwire(dev, signal, &status);
|
||||
k_busy_wait(200);
|
||||
|
||||
switch (signal) {
|
||||
case ESPI_VWIRE_SIGNAL_SUS_WARN:
|
||||
vw_signal_set_valid(dev, ESPI_VWIRE_SIGNAL_SUS_ACK, 1);
|
||||
espi_rts5912_send_vwire(dev, ESPI_VWIRE_SIGNAL_SUS_ACK, status);
|
||||
break;
|
||||
case ESPI_VWIRE_SIGNAL_OOB_RST_WARN:
|
||||
espi_rts5912_send_vwire(dev, ESPI_VWIRE_SIGNAL_OOB_RST_ACK, status);
|
||||
break;
|
||||
case ESPI_VWIRE_SIGNAL_HOST_RST_WARN:
|
||||
espi_rts5912_send_vwire(dev, ESPI_VWIRE_SIGNAL_HOST_RST_ACK, status);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void vw_slp3_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SLP_S3);
|
||||
}
|
||||
|
||||
static void vw_slp4_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SLP_S4);
|
||||
}
|
||||
|
||||
static void vw_slp5_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SLP_S5);
|
||||
}
|
||||
|
||||
static void vw_sus_stat_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SUS_STAT);
|
||||
}
|
||||
|
||||
static void vw_pltrst_handler(const struct device *dev)
|
||||
{
|
||||
struct espi_rts5912_data *data = dev->data;
|
||||
|
||||
struct espi_event evt = {ESPI_BUS_EVENT_VWIRE_RECEIVED, ESPI_VWIRE_SIGNAL_PLTRST, 0};
|
||||
uint8_t status = 0;
|
||||
|
||||
espi_rts5912_receive_vwire(dev, ESPI_VWIRE_SIGNAL_PLTRST, &status);
|
||||
|
||||
if (status) {
|
||||
vw_signal_set_valid(dev, ESPI_VWIRE_SIGNAL_SMI, 1);
|
||||
vw_signal_set_valid(dev, ESPI_VWIRE_SIGNAL_SCI, 1);
|
||||
vw_signal_set_valid(dev, ESPI_VWIRE_SIGNAL_HOST_RST_ACK, 1);
|
||||
vw_signal_set_valid(dev, ESPI_VWIRE_SIGNAL_RST_CPU_INIT, 1);
|
||||
|
||||
espi_rts5912_send_vwire(dev, ESPI_VWIRE_SIGNAL_SMI, 1);
|
||||
espi_rts5912_send_vwire(dev, ESPI_VWIRE_SIGNAL_SCI, 1);
|
||||
espi_rts5912_send_vwire(dev, ESPI_VWIRE_SIGNAL_HOST_RST_ACK, 1);
|
||||
espi_rts5912_send_vwire(dev, ESPI_VWIRE_SIGNAL_RST_CPU_INIT, 1);
|
||||
}
|
||||
|
||||
evt.evt_data = status;
|
||||
espi_send_callbacks(&data->callbacks, dev, evt);
|
||||
}
|
||||
|
||||
static void vw_oob_rst_warn_handler(const struct device *dev)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE)) {
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_OOB_RST_WARN);
|
||||
} else {
|
||||
notify_host_warning(dev, ESPI_VWIRE_SIGNAL_OOB_RST_WARN);
|
||||
}
|
||||
}
|
||||
|
||||
static void vw_host_rst_warn_handler(const struct device *dev)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE)) {
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_HOST_RST_WARN);
|
||||
} else {
|
||||
notify_host_warning(dev, ESPI_VWIRE_SIGNAL_HOST_RST_WARN);
|
||||
}
|
||||
}
|
||||
|
||||
static void vw_smiout_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SMIOUT);
|
||||
}
|
||||
|
||||
static void vw_nmiout_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_NMIOUT);
|
||||
}
|
||||
|
||||
static void vw_sus_warn_handler(const struct device *dev)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE)) {
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SUS_WARN);
|
||||
} else {
|
||||
notify_host_warning(dev, ESPI_VWIRE_SIGNAL_SUS_WARN);
|
||||
}
|
||||
}
|
||||
|
||||
static void vw_sus_pwrdn_ack_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SUS_PWRDN_ACK);
|
||||
}
|
||||
|
||||
static void vw_sus_slp_a_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SLP_A);
|
||||
}
|
||||
|
||||
static void vw_slp_lan_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SLP_LAN);
|
||||
}
|
||||
|
||||
static void vw_slp_wlan_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SLP_WLAN);
|
||||
}
|
||||
|
||||
static void vw_host_c10_handler(const struct device *dev)
|
||||
{
|
||||
notify_system_state(dev, ESPI_VWIRE_SIGNAL_HOST_C10);
|
||||
}
|
||||
|
||||
#define VW_TIMEOUT_US 1000
|
||||
|
||||
static int espi_rts5912_send_vwire(const struct device *dev, enum espi_vwire_signal signal,
|
||||
uint8_t level)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
|
||||
uint8_t vw_idx = vw_channel_list[signal].vw_index;
|
||||
uint8_t lev_msk = vw_channel_list[signal].level_mask;
|
||||
uint32_t tx_data = 0;
|
||||
|
||||
if (signal > ARRAY_SIZE(vw_channel_list)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
switch (vw_idx) {
|
||||
case VW_CH_IDX4:
|
||||
tx_data = espi_vw_tx_cached_data.idx4;
|
||||
break;
|
||||
case VW_CH_IDX5:
|
||||
tx_data = espi_vw_tx_cached_data.idx5;
|
||||
break;
|
||||
case VW_CH_IDX6:
|
||||
tx_data = espi_vw_tx_cached_data.idx6;
|
||||
break;
|
||||
case VW_CH_IDX40:
|
||||
tx_data = espi_vw_tx_cached_data.idx40;
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
tx_data |= (vw_idx << 8);
|
||||
|
||||
if (level) {
|
||||
tx_data |= lev_msk;
|
||||
} else {
|
||||
tx_data &= ~lev_msk;
|
||||
}
|
||||
|
||||
if (espi_reg->EVSTS & ESPI_EVSTS_TXFULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
espi_reg->EVTXDAT = tx_data;
|
||||
|
||||
WAIT_FOR(!(espi_reg->EVSTS & ESPI_EVSTS_TXFULL), VW_TIMEOUT_US, k_busy_wait(10));
|
||||
|
||||
switch (vw_idx) {
|
||||
case VW_CH_IDX4:
|
||||
espi_vw_tx_cached_data.idx4 = tx_data;
|
||||
break;
|
||||
case VW_CH_IDX5:
|
||||
espi_vw_tx_cached_data.idx5 = tx_data;
|
||||
break;
|
||||
case VW_CH_IDX6:
|
||||
espi_vw_tx_cached_data.idx6 = tx_data;
|
||||
break;
|
||||
case VW_CH_IDX40:
|
||||
espi_vw_tx_cached_data.idx40 = tx_data;
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_signal signal,
|
||||
uint8_t *level)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
uint8_t vw_idx, lev_msk, valid_msk;
|
||||
uint8_t vw_data;
|
||||
|
||||
vw_idx = vw_channel_list[signal].vw_index;
|
||||
lev_msk = vw_channel_list[signal].level_mask;
|
||||
valid_msk = vw_channel_list[signal].valid_mask;
|
||||
|
||||
if (signal > ARRAY_SIZE(vw_channel_list)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
switch (vw_idx) {
|
||||
case VW_CH_IDX2:
|
||||
vw_data = espi_vw_ch_cached_data.idx2;
|
||||
break;
|
||||
case VW_CH_IDX3:
|
||||
if (espi_vw_ch_cached_data.idx3 != espi_reg->EVIDX3) {
|
||||
espi_vw_ch_cached_data.idx3 = espi_reg->EVIDX3;
|
||||
}
|
||||
vw_data = espi_vw_ch_cached_data.idx3;
|
||||
break;
|
||||
case VW_CH_IDX4:
|
||||
vw_data = espi_vw_tx_cached_data.idx4;
|
||||
break;
|
||||
case VW_CH_IDX5:
|
||||
vw_data = espi_vw_tx_cached_data.idx5;
|
||||
break;
|
||||
case VW_CH_IDX6:
|
||||
vw_data = espi_vw_tx_cached_data.idx6;
|
||||
break;
|
||||
case VW_CH_IDX7:
|
||||
if (espi_vw_ch_cached_data.idx7 != espi_reg->EVIDX7) {
|
||||
espi_vw_ch_cached_data.idx7 = espi_reg->EVIDX7;
|
||||
}
|
||||
vw_data = espi_vw_ch_cached_data.idx7;
|
||||
break;
|
||||
case VW_CH_IDX40:
|
||||
vw_data = espi_vw_tx_cached_data.idx40;
|
||||
break;
|
||||
case VW_CH_IDX41:
|
||||
if (espi_vw_ch_cached_data.idx41 != espi_reg->EVIDX41) {
|
||||
espi_vw_ch_cached_data.idx41 = espi_reg->EVIDX41;
|
||||
}
|
||||
vw_data = espi_vw_ch_cached_data.idx41;
|
||||
break;
|
||||
case VW_CH_IDX42:
|
||||
if (espi_vw_ch_cached_data.idx42 != espi_reg->EVIDX42) {
|
||||
espi_vw_ch_cached_data.idx42 = espi_reg->EVIDX42;
|
||||
}
|
||||
vw_data = espi_vw_ch_cached_data.idx42;
|
||||
break;
|
||||
case VW_CH_IDX43:
|
||||
if (espi_vw_ch_cached_data.idx43 != espi_reg->EVIDX43) {
|
||||
espi_vw_ch_cached_data.idx43 = espi_reg->EVIDX43;
|
||||
}
|
||||
vw_data = espi_vw_ch_cached_data.idx43;
|
||||
break;
|
||||
case VW_CH_IDX44:
|
||||
if (espi_vw_ch_cached_data.idx44 != espi_reg->EVIDX44) {
|
||||
espi_vw_ch_cached_data.idx44 = espi_reg->EVIDX44;
|
||||
}
|
||||
vw_data = espi_vw_ch_cached_data.idx44;
|
||||
break;
|
||||
case VW_CH_IDX47:
|
||||
if (espi_vw_ch_cached_data.idx47 != espi_reg->EVIDX47) {
|
||||
espi_vw_ch_cached_data.idx47 = espi_reg->EVIDX47;
|
||||
}
|
||||
vw_data = espi_vw_ch_cached_data.idx47;
|
||||
break;
|
||||
case VW_CH_IDX4A:
|
||||
if (espi_vw_ch_cached_data.idx4a != espi_reg->EVIDX4A) {
|
||||
espi_vw_ch_cached_data.idx4a = espi_reg->EVIDX4A;
|
||||
}
|
||||
vw_data = espi_vw_ch_cached_data.idx4a;
|
||||
break;
|
||||
case VW_CH_IDX51:
|
||||
if (espi_vw_ch_cached_data.idx51 != espi_reg->EVIDX51) {
|
||||
espi_vw_ch_cached_data.idx51 = espi_reg->EVIDX51;
|
||||
}
|
||||
vw_data = espi_vw_ch_cached_data.idx51;
|
||||
break;
|
||||
case VW_CH_IDX61:
|
||||
if (espi_vw_ch_cached_data.idx61 != espi_reg->EVIDX61) {
|
||||
espi_vw_ch_cached_data.idx61 = espi_reg->EVIDX61;
|
||||
}
|
||||
vw_data = espi_vw_ch_cached_data.idx61;
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_ESPI_VWIRE_VALID_BIT_CHECK)) {
|
||||
if (vw_data & valid_msk) {
|
||||
*level = !!(vw_data & lev_msk);
|
||||
} else {
|
||||
/* Not valid */
|
||||
*level = 0;
|
||||
}
|
||||
} else {
|
||||
*level = !!(vw_data & lev_msk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void espi_vw_ch_setup(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
|
||||
|
||||
espi_reg->EVSTS |= ESPI_EVSTS_RXIDXCLR;
|
||||
|
||||
espi_vw_ch_cached_data.idx2 = espi_reg->EVIDX2;
|
||||
espi_vw_ch_cached_data.idx3 = espi_reg->EVIDX3;
|
||||
espi_vw_ch_cached_data.idx7 = espi_reg->EVIDX7;
|
||||
espi_vw_ch_cached_data.idx41 = espi_reg->EVIDX41;
|
||||
espi_vw_ch_cached_data.idx42 = espi_reg->EVIDX42;
|
||||
espi_vw_ch_cached_data.idx43 = espi_reg->EVIDX43;
|
||||
espi_vw_ch_cached_data.idx44 = espi_reg->EVIDX44;
|
||||
espi_vw_ch_cached_data.idx47 = espi_reg->EVIDX47;
|
||||
espi_vw_ch_cached_data.idx4a = espi_reg->EVIDX4A;
|
||||
espi_vw_ch_cached_data.idx51 = espi_reg->EVIDX51;
|
||||
espi_vw_ch_cached_data.idx61 = espi_reg->EVIDX61;
|
||||
|
||||
espi_vw_tx_cached_data.idx4 = 0;
|
||||
espi_vw_tx_cached_data.idx5 = 0;
|
||||
espi_vw_tx_cached_data.idx6 = 0;
|
||||
espi_vw_tx_cached_data.idx40 = 0;
|
||||
|
||||
espi_reg->EVRXINTEN = (ESPI_EVRXINTEN_CFGCHGEN | ESPI_EVRXINTEN_RXCHGEN);
|
||||
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_ch, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx2, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx3, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx7, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx41, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx42, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx43, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx44, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx47, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx4a, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx51, irq));
|
||||
NVIC_ClearPendingIRQ(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx61, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_ch, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_ch, priority), espi_vw_ch_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_ch, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx2, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx2, priority), espi_vw_idx2_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx2, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx3, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx3, priority), espi_vw_idx3_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx3, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx7, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx7, priority), espi_vw_idx7_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx7, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx41, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx41, priority), espi_vw_idx41_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx41, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx42, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx42, priority), espi_vw_idx42_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx42, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx43, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx43, priority), espi_vw_idx43_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx43, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx44, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx44, priority), espi_vw_idx44_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx44, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx47, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx47, priority), espi_vw_idx47_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx47, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx4a, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx4a, priority), espi_vw_idx4a_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx4a, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx51, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx51, priority), espi_vw_idx51_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx51, irq));
|
||||
|
||||
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx61, irq),
|
||||
DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx61, priority), espi_vw_idx61_isr,
|
||||
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
|
||||
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), vw_idx61, irq));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ESPI_VWIRE_CHANNEL */
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* ESPI OOB channel
|
||||
|
@ -196,6 +1081,11 @@ static void espi_oob_chg_isr(const struct device *dev)
|
|||
if (status & ESPI_EOSTS_CFGENCHG) {
|
||||
evt.evt_data = config & ESPI_EVCFG_CHEN ? 1 : 0;
|
||||
espi_send_callbacks(&espi_data->callbacks, dev, evt);
|
||||
|
||||
if (config & ESPI_EVCFG_CHEN) {
|
||||
vw_signal_set_valid(dev, ESPI_VWIRE_SIGNAL_OOB_RST_ACK, 1);
|
||||
}
|
||||
|
||||
espi_reg->EOSTS = ESPI_EOSTS_CFGENCHG;
|
||||
}
|
||||
}
|
||||
|
@ -574,6 +1464,10 @@ static DEVICE_API(espi, espi_rts5912_driver_api) = {
|
|||
.config = espi_rts5912_configure,
|
||||
.get_channel_status = espi_rts5912_channel_ready,
|
||||
.manage_callback = espi_rts5912_manage_callback,
|
||||
#ifdef CONFIG_ESPI_VWIRE_CHANNEL
|
||||
.send_vwire = espi_rts5912_send_vwire,
|
||||
.receive_vwire = espi_rts5912_receive_vwire,
|
||||
#endif
|
||||
#ifdef CONFIG_ESPI_OOB_CHANNEL
|
||||
.send_oob = espi_rts5912_send_oob,
|
||||
.receive_oob = espi_rts5912_receive_oob,
|
||||
|
@ -585,6 +1479,10 @@ static DEVICE_API(espi, espi_rts5912_driver_api) = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static void espi_vw_ch_setup(const struct device *dev);
|
||||
|
||||
#define VW_RESET_DELAY 150UL
|
||||
|
||||
static void espi_rst_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_rts5912_config *const espi_config = dev->config;
|
||||
|
@ -605,6 +1503,15 @@ static void espi_rst_isr(const struct device *dev)
|
|||
} else {
|
||||
/* rst pin low go high trigger interrupt */
|
||||
evt.evt_data = 1;
|
||||
#ifdef CONFIG_ESPI_VWIRE_CHANNEL
|
||||
espi_vw_ch_setup(dev);
|
||||
espi_reg->ESPICFG = data->config_data;
|
||||
if (espi_reg->EVCFG & ESPI_EVCFG_CHEN) {
|
||||
k_timeout_t delay = K_MSEC(VW_RESET_DELAY);
|
||||
|
||||
k_work_schedule(&vw_ch_isr_wa, delay);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
espi_send_callbacks(&data->callbacks, dev, evt);
|
||||
}
|
||||
|
@ -666,6 +1573,11 @@ static int espi_rts5912_init(const struct device *dev)
|
|||
/* Setup eSPI bus reset */
|
||||
espi_bus_reset_setup(dev);
|
||||
|
||||
#ifdef CONFIG_ESPI_VWIRE_CHANNEL
|
||||
/* Setup eSPI virtual-wire channel */
|
||||
espi_vw_ch_setup(dev);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPI_OOB_CHANNEL
|
||||
/* Setup eSPI OOB channel */
|
||||
rc = espi_oob_ch_setup(dev);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue