FreeCalypso > hg > freecalypso-sw
diff target-utils/libbase/abbdrv.c @ 991:5cff3579814c
target-utils: libbase factored out of libcommon
The library dependency order is now strictly unidirectional
author | Mychaela Falconia <falcon@ivan.Harhan.ORG> |
---|---|
date | Wed, 30 Dec 2015 20:48:12 +0000 |
parents | target-utils/libcommon/abbdrv.c@6661e5bc0712 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libbase/abbdrv.c Wed Dec 30 20:48:12 2015 +0000 @@ -0,0 +1,102 @@ +/* Driver for Analog Baseband Circuit (TWL3025) */ +/* lifted from OsmocomBB and ported to FreeCalypso target-utils environment */ + +/* (C) 2010 by Harald Welte <laforge@gnumonks.org> + * + * All Rights Reserved + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "types.h" +#include "abbdefs.h" + +/* TWL3025 */ +#define REG_PAGE(n) ((n) >> 7) +#define REG_ADDR(n) ((n) & 0x1f) + +#define TWL3025_DEV_IDX 0 /* On the SPI bus */ +#define TWL3025_TSP_DEV_IDX 0 /* On the TSP bus */ + +int abb_state_initdone, abb_state_page; + +void +abb_reg_write(reg, data) +{ + u16 tx; + + if (reg != PAGEREG && REG_PAGE(reg) != abb_state_page) + abb_select_page(REG_PAGE(reg)); + + tx = ((data & 0x3ff) << 6) | (REG_ADDR(reg) << 1); + + spi_xfer(TWL3025_DEV_IDX, 16, &tx, 0); +} + +u16 +abb_reg_read(reg) +{ + u16 tx, rx; + + if (REG_PAGE(reg) != abb_state_page) + abb_select_page(REG_PAGE(reg)); + + tx = (REG_ADDR(reg) << 1) | 1; + + /* A read cycle contains two SPI transfers */ + spi_xfer(TWL3025_DEV_IDX, 16, &tx, &rx); + osmo_delay_ms(1); + spi_xfer(TWL3025_DEV_IDX, 16, &tx, &rx); + + rx >>= 6; + + return rx; +} + +/* Switch the register page of the TWL3025 */ +abb_select_page(page) +{ + if (page == 0) + abb_reg_write(PAGEREG, 1 << 0); + else + abb_reg_write(PAGEREG, 1 << 1); + abb_state_page = page; + return(0); +} + +abb_init() +{ + if (abb_state_initdone) + return(0); + spi_init(); + abb_select_page(0); + /* CLK13M enable */ + abb_reg_write(TOGBR2, TOGBR2_ACTS); + osmo_delay_ms(1); + /* for whatever reason we need to do this twice */ + abb_reg_write(TOGBR2, TOGBR2_ACTS); + osmo_delay_ms(1); + abb_state_initdone = 1; + return(1); +} + +void +abb_power_off() +{ + abb_init(); + serial_flush(); + abb_reg_write(VRPCDEV, 0x01); +}