#include #include #include "l1110.h" #include "soc_common.h" enum { PRS_S1 = BIT(0), PRS_S2 = BIT(1), PRS_S3 = BIT(2), PRS_S4 = BIT(3), PRS_BVD1 = BIT(4), PRS_BVD2 = BIT(5), PRS_VS1 = BIT(6), PRS_VS2 = BIT(7), PRS_RDY = BIT(8), PRS_CD1 = BIT(9), PRS_CD2 = BIT(10), PRC_S1 = PRS_S1, /* x1vcc - TPS2205 D2/D7 */ PRC_S2 = PRS_S2, /* x0vcc - TPS2205 D3/D6 */ PRC_S3 = PRS_S3, /* x0vpp - TPS2205 D1/D5 */ PRC_S4 = PRS_S4, /* x1vpp - TPS2205 D0/D4 */ PRC_RST = BIT(4), PRC_APOE = BIT(5), /* auto power off enable */ PRC_CFE = BIT(6), /* CF enable: A25:11 driven high */ PRC_SOE = BIT(7), /* signal output enable */ PRC_SSP = BIT(8), /* socket select polarity */ }; struct l1110 { void __iomem *reg; u16 prc; }; int l1110_init(struct device *dev, struct l1110 **ptr, resource_size_t base, unsigned int ssp) { struct l1110 *l; l = devm_kzalloc(dev, sizeof(*l), GFP_KERNEL); if (!l) return -ENOMEM; l->prc = PRC_APOE | (ssp ? PRC_SSP : 0); l->reg = devm_ioremap(dev, base, 2); if (!l->reg) return -ENOMEM; *ptr = l; writew_relaxed(l->prc, l->reg); return 0; } EXPORT_SYMBOL_GPL(l1110_init); void l1110_socket_state(struct l1110 *l, struct pcmcia_state *state) { u16 prs = readw_relaxed(l->reg); state->bvd1 = !!(prs & PRS_BVD1); state->bvd2 = !!(prs & PRS_BVD2); state->vs_3v = !(prs & PRS_VS1); state->vs_Xv = !(prs & PRS_VS2); } EXPORT_SYMBOL_GPL(l1110_socket_state); int l1110_configure_socket(struct l1110 *l, const socket_state_t *state) { u16 prc = l->prc; switch (state->Vcc) { case 0: break; case 33: prc |= PRC_S1; break; case 50: prc |= PRC_S2; break; default: return -EINVAL; } if (state->Vpp) { if (state->Vpp == 12) prc |= PRC_S4; else if (state->Vpp == state->Vcc) prc |= PRC_S3; else return -EINVAL; } if (state->flags & SS_RESET) prc |= PRC_RST; if (state->flags & SS_OUTPUT_ENA) prc |= PRC_SOE; writew_relaxed(prc, l->reg); return 0; } EXPORT_SYMBOL_GPL(l1110_configure_socket); MODULE_AUTHOR("Russell King "); MODULE_DESCRIPTION("LinkUp Systems L1110 driver"); MODULE_LICENSE("GPL");