in i82365.c [922:1028]
static int i365_set_socket(u_short sock, socket_state_t *state)
{
struct i82365_socket *t = &socket[sock];
u_char reg;
pr_debug("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
"io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
/* First set global controller options */
set_bridge_state(sock);
/* IO card, RESET flag, IO interrupt */
reg = t->intr;
reg |= state->io_irq;
reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
i365_set(sock, I365_INTCTL, reg);
reg = I365_PWR_NORESET;
if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
if (t->flags & IS_CIRRUS) {
if (state->Vpp != 0) {
if (state->Vpp == 120)
reg |= I365_VPP1_12V;
else if (state->Vpp == state->Vcc)
reg |= I365_VPP1_5V;
else return -EINVAL;
}
if (state->Vcc != 0) {
reg |= I365_VCC_5V;
if (state->Vcc == 33)
i365_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
else if (state->Vcc == 50)
i365_bclr(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
else return -EINVAL;
}
} else if (t->flags & IS_VG_PWR) {
if (state->Vpp != 0) {
if (state->Vpp == 120)
reg |= I365_VPP1_12V;
else if (state->Vpp == state->Vcc)
reg |= I365_VPP1_5V;
else return -EINVAL;
}
if (state->Vcc != 0) {
reg |= I365_VCC_5V;
if (state->Vcc == 33)
i365_bset(sock, VG469_VSELECT, VG469_VSEL_VCC);
else if (state->Vcc == 50)
i365_bclr(sock, VG469_VSELECT, VG469_VSEL_VCC);
else return -EINVAL;
}
} else if (t->flags & IS_DF_PWR) {
switch (state->Vcc) {
case 0: break;
case 33: reg |= I365_VCC_3V; break;
case 50: reg |= I365_VCC_5V; break;
default: return -EINVAL;
}
switch (state->Vpp) {
case 0: break;
case 50: reg |= I365_VPP1_5V; break;
case 120: reg |= I365_VPP1_12V; break;
default: return -EINVAL;
}
} else {
switch (state->Vcc) {
case 0: break;
case 50: reg |= I365_VCC_5V; break;
default: return -EINVAL;
}
switch (state->Vpp) {
case 0: break;
case 50: reg |= I365_VPP1_5V | I365_VPP2_5V; break;
case 120: reg |= I365_VPP1_12V | I365_VPP2_12V; break;
default: return -EINVAL;
}
}
if (reg != i365_get(sock, I365_POWER))
i365_set(sock, I365_POWER, reg);
/* Chipset-specific functions */
if (t->flags & IS_CIRRUS) {
/* Speaker control */
i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA,
state->flags & SS_SPKR_ENA);
}
/* Card status change interrupt mask */
reg = t->cs_irq << 4;
if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
if (state->flags & SS_IOCARD) {
if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
} else {
if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
}
i365_set(sock, I365_CSCINT, reg);
i365_get(sock, I365_CSC);
return 0;
} /* i365_set_socket */