/* * libubb/ubb.c - Open/close UBB * * Written 2012 by Werner Almesberger * Copyright 2012 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include volatile void *ubb_mem; static int ubb_fd; static uint32_t data, dir, pull, func, sel; static void *map(off_t addr, size_t size, int *fd) { void *mem; *fd = open("/dev/mem", O_RDWR | O_SYNC); if (*fd < 0) return NULL; mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, addr); if (mem == MAP_FAILED) { (void) close(*fd); return NULL; } return mem; } int ubb_open(uint32_t keep) { ubb_mem = map(UBB_SOC_BASE, UBB_REG_WINDOW, &ubb_fd); if (!ubb_mem) return -1; data = PDDAT & UBB_ALL; dir = PDDIR & UBB_ALL; pull = PDPULL & UBB_ALL; func = PDFUN & UBB_ALL; sel = PDSEL & UBB_ALL; /* enable pull-ups to let card ramp up power */ PDPULLC = UBB_ALL_IO & ~keep; PDDIRC = UBB_ALL_IO & ~keep; PDFUNC = UBB_ALL & ~keep; PDSELC = UBB_ALL & ~keep; PDDATS = UBB_nPWR & ~keep; PDDIRS = UBB_nPWR & ~keep; return 0; } void ubb_power(int on) { if (on) { usleep(10*1000); PDDATC = UBB_nPWR; } else { PDDATS = UBB_nPWR; } } void ubb_close(uint32_t keep) { PDSELS = sel & ~keep; PDFUNS = func & ~keep; PDDATS = (data | UBB_nPWR) & ~keep; PDDIRS = (dir | UBB_nPWR) & ~keep; PDPULLS = pull & ~keep; close(ubb_fd); }