diff --git a/ccid_common/ccid_slot_fsm.c b/ccid_common/ccid_slot_fsm.c index a00375e..99c8c21 100644 --- a/ccid_common/ccid_slot_fsm.c +++ b/ccid_common/ccid_slot_fsm.c @@ -77,7 +77,7 @@ static void iso_fsm_slot_icc_set_insertion_status(struct ccid_slot *cs, bool pre if (!present) { osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_CARD_REMOVAL, NULL); card_uart_ctrl(ss->cuart, CUART_CTL_RST, true); - card_uart_ctrl(ss->cuart, CUART_CTL_POWER, false); + card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, false); cs->icc_powered = false; cs->cmd_busy = false; } @@ -87,15 +87,24 @@ static void iso_fsm_slot_icc_power_on_async(struct ccid_slot *cs, struct msgb *m const struct ccid_pc_to_rdr_icc_power_on *ipo) { struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs); + enum ccid_power_select pwrsel = ipo->bPowerSelect; + enum card_uart_ctl cctl; ss->seq = ipo->hdr.bSeq; LOGPCS(cs, LOGL_DEBUG, "scheduling power-up\n"); + switch (pwrsel) { + case CCID_PWRSEL_5V0: cctl = CUART_CTL_POWER_5V0; break; + case CCID_PWRSEL_3V0: cctl = CUART_CTL_POWER_3V0; break; + case CCID_PWRSEL_1V8: cctl = CUART_CTL_POWER_1V8; break; + default: cctl = CUART_CTL_POWER_5V0; + } + if (! cs->icc_powered) { /* FIXME: do this via a FSM? */ card_uart_ctrl(ss->cuart, CUART_CTL_RST, true); osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_RESET_ACT_IND, NULL); - card_uart_ctrl(ss->cuart, CUART_CTL_POWER, true); + card_uart_ctrl(ss->cuart, cctl, true); osmo_fsm_inst_dispatch(ss->fi, ISO7816_E_POWER_UP_IND, NULL); cs->icc_powered = true; card_uart_ctrl(ss->cuart, CUART_CTL_CLOCK, true); @@ -166,7 +175,7 @@ static int iso_handle_fsm_events(struct ccid_slot *cs, bool enable){ /* perform deactivation */ card_uart_ctrl(ss->cuart, CUART_CTL_RST, true); - card_uart_ctrl(ss->cuart, CUART_CTL_POWER, false); + card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, false); cs->icc_powered = false; @@ -285,10 +294,10 @@ static void iso_fsm_slot_set_power(struct ccid_slot *cs, bool enable) struct iso_fsm_slot *ss = ccid_slot2iso_fsm_slot(cs); if (enable) { - card_uart_ctrl(ss->cuart, CUART_CTL_POWER, true); + card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, true); cs->icc_powered = true; } else { - card_uart_ctrl(ss->cuart, CUART_CTL_POWER, false); + card_uart_ctrl(ss->cuart, CUART_CTL_POWER_5V0, false); cs->icc_powered = false; } } diff --git a/ccid_common/cuart.h b/ccid_common/cuart.h index 1df0c49..6f8ba70 100644 --- a/ccid_common/cuart.h +++ b/ccid_common/cuart.h @@ -25,7 +25,9 @@ enum card_uart_ctl { CUART_CTL_RX, /* enable/disable receiver */ CUART_CTL_RX_TIMER_HINT, /* tell cuart approximate number of rx bytes */ CUART_CTL_NO_RXTX, /* enable/disable receiver */ - CUART_CTL_POWER, /* enable/disable ICC power */ + CUART_CTL_POWER_5V0, + CUART_CTL_POWER_3V0, + CUART_CTL_POWER_1V8, CUART_CTL_CLOCK, /* enable/disable ICC clock */ CUART_CTL_SET_CLOCK_FREQ, /* set ICC clock frequency (hz)*/ CUART_CTL_RST, /* enable/disable ICC reset */ diff --git a/ccid_host/cuart_driver_tty.c b/ccid_host/cuart_driver_tty.c index 5f635b5..42a8430 100644 --- a/ccid_host/cuart_driver_tty.c +++ b/ccid_host/cuart_driver_tty.c @@ -284,7 +284,9 @@ static int tty_uart_ctrl(struct card_uart *cuart, enum card_uart_ctl ctl, int ar case CUART_CTL_WTIME: /* no driver-specific handling of this */ break; - case CUART_CTL_POWER: + case CUART_CTL_POWER_5V0: + case CUART_CTL_POWER_3V0: + case CUART_CTL_POWER_1V8: case CUART_CTL_CLOCK: default: return -EINVAL; diff --git a/ccid_host/cuart_fsm_test.c b/ccid_host/cuart_fsm_test.c index 5b03bfe..38cad14 100644 --- a/ccid_host/cuart_fsm_test.c +++ b/ccid_host/cuart_fsm_test.c @@ -79,7 +79,7 @@ int main(int argc, char **argv) /* activate reset, then power up */ card_uart_ctrl(&g_cuart, CUART_CTL_RST, true); - card_uart_ctrl(&g_cuart, CUART_CTL_POWER, true); + card_uart_ctrl(&g_cuart, CUART_CTL_POWER_1V8, true); osmo_fsm_inst_dispatch(fi, ISO7816_E_POWER_UP_IND, NULL); /* activate clock */ diff --git a/sysmoOCTSIM/cuart_driver_asf4_usart_async.c b/sysmoOCTSIM/cuart_driver_asf4_usart_async.c index 0e83385..89cd734 100644 --- a/sysmoOCTSIM/cuart_driver_asf4_usart_async.c +++ b/sysmoOCTSIM/cuart_driver_asf4_usart_async.c @@ -373,15 +373,32 @@ static int asf4_usart_ctrl(struct card_uart *cuart, enum card_uart_ctl ctl, int settings.rstin = arg ? true : false; ncn8025_set(cuart->u.asf4.slot_nr, &settings); usart_async_flush_rx_buffer(cuart->u.asf4.usa_pd); + + /* reset everything, card reset resets pps params */ + if (arg) + slot_set_isorate(cuart, SIM_CLKDIV_8, ISO7816_3_DEFAULT_FD, ISO7816_3_DEFAULT_DD); + break; - case CUART_CTL_POWER: + + case CUART_CTL_POWER_5V0: + case CUART_CTL_POWER_3V0: + case CUART_CTL_POWER_1V8: /* reset everything */ slot_set_isorate(cuart, SIM_CLKDIV_8, ISO7816_3_DEFAULT_FD, ISO7816_3_DEFAULT_DD); + + enum ncn8025_sim_voltage v = CUART_CTL_POWER_5V0; + switch (ctl) { + case CUART_CTL_POWER_5V0: v = SIM_VOLT_5V0; break; + case CUART_CTL_POWER_3V0: v = SIM_VOLT_3V0; break; + case CUART_CTL_POWER_1V8: v = SIM_VOLT_1V8; break; + default: break; + } + ncn8025_get(cuart->u.asf4.slot_nr, &settings); settings.cmdvcc = arg ? true : false; settings.led = arg ? true : false; - settings.vsel = SIM_VOLT_5V0; + settings.vsel = v; ncn8025_set(cuart->u.asf4.slot_nr, &settings); break;