view target-utils/libbase/abbdrv.c @ 496:3d73d4d3527f

target-utils: removed osmo_delay_ms() from ABB access code
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 25 May 2019 20:17:27 +0000
parents e7502631a0f9
children 74610c4f10f7
line wrap: on
line source

/* 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);
	/* delay of seven 13MHz cycles */
	wait_ARM_cycles(7);
	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);
	/* ABB_Wait_IBIC_Access() delay of 210 us */
	wait_ARM_cycles(210 * 13);
	/* for whatever reason we need to do this twice */
	abb_reg_write(TOGBR2, TOGBR2_ACTS);
	/* ABB_Wait_IBIC_Access() delay of 210 us */
	wait_ARM_cycles(210 * 13);
	abb_state_initdone = 1;
	return(1);
}

void
abb_power_off()
{
	abb_init();
	serial_flush();
	abb_reg_write(VRPCDEV, 0x01);
}