view target-utils/libbase/abbdrv.c @ 497:74610c4f10f7

target-utils: added 10 ms delay at the end of abb_power_off() The deosmification of the ABB access code (replacement of osmo_delay_ms() bogus delays with correctly-timed ones, which are significantly shorter) had one annoying side effect: when executing the poweroff command from any of the programs, one last '=' prompt character was being sent (and received by the x86 host) as the Calypso board powers off. With delays being shorter now, the abb_power_off() function was returning and the standalone program's main loop was printing its prompt before the Iota chip fully executed the switch-off sequence! I thought about inserting an endless tight loop at the end of the abb_power_off() function, but the implemented solution of a 10 ms delay is a little nicer IMO because if the DEVOFF operation doesn't happen for some reason in a manual hacking scenario, there won't be an artificial blocker in the form of a tight loop keeping us from further poking around.
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 25 May 2019 20:44:05 +0000
parents 3d73d4d3527f
children 44a1de4264d8
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);
	/*
	 * TWL3025 datasheet seems to indicate that the time for the DEVOFF
	 * command to take effect is 5 cycles of the 32.768 kHz clock.
	 * We'll do an ARM-timed delay of 10 ms before returning from
	 * this function.
	 */
	wait_ARM_cycles(13000 * 10);
}