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);
+}