# HG changeset patch # User Michael Spacefalcon # Date 1402469446 0 # Node ID e60aecf23970afb801c6c939b2a060e42d818d6b # Parent 821a26f909686bf5b7130410588ccb855b363af7 target-utils: ABB operations implemented (ported from OsmocomBB), linked into pirexplore diff -r 821a26f90968 -r e60aecf23970 target-utils/include/abbdefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/include/abbdefs.h Wed Jun 11 06:50:46 2014 +0000 @@ -0,0 +1,155 @@ +/* lifted from OsmocomBB */ + +#ifndef _TWL3025_H +#define _TWL3025_H + +#define PAGE(n) (n << 7) +enum twl3025_reg { + VRPCCFG = PAGE(1) | 30, + VRPCDEV = PAGE(0) | 30, + VRPCMSK = PAGE(1) | 31, + VRPCMSKABB = PAGE(1) | 29, + VRPCSTS = PAGE(0) | 31, + /* Monitoring ADC Registers */ + MADCTRL = PAGE(0) | 13, + MADCSTAT = PAGE(0) | 24, + VBATREG = PAGE(0) | 15, + VCHGREG = PAGE(0) | 16, + ICHGREG = PAGE(0) | 17, + VBKPREG = PAGE(0) | 18, + ADIN1REG = PAGE(0) | 19, + ADIN2REG = PAGE(0) | 20, + ADIN3REG = PAGE(0) | 21, + ADIN4REG = PAGE(0) | 22, + /* Clock Generator Registers */ + TOGBR1 = PAGE(0) | 4, + TOGBR2 = PAGE(0) | 5, + PWDNRG = PAGE(1) | 9, + TAPCTRL = PAGE(1) | 19, + TAPREG = PAGE(1) | 20, + /* Automatic Frequency Control (AFC) Registers */ + AUXAFC1 = PAGE(0) | 7, + AUXAFC2 = PAGE(0) | 8, + AFCCTLADD = PAGE(1) | 21, + AFCOUT = PAGE(1) | 22, + /* Automatic Power Control (APC) Registers */ + APCDEL1 = PAGE(0) | 2, + APCDEL2 = PAGE(1) | 26, + AUXAPC = PAGE(0) | 9, + APCRAM = PAGE(0) | 10, + APCOFF = PAGE(0) | 11, + APCOUT = PAGE(1) | 12, + /* Auxiliary DAC Control Register */ + AUXDAC = PAGE(0) | 12, + /* SimCard Control Register */ + VRPCSIM = PAGE(1) | 23, + /* LED Driver Register */ + AUXLED = PAGE(1) | 24, + /* Battery Charger Interface (BCI) Registers */ + CHGREG = PAGE(0) | 25, + BCICTL1 = PAGE(0) | 28, + BCICTL2 = PAGE(0) | 29, + BCICONF = PAGE(1) | 13, + /* Interrupt and Bus Control (IBIC) Registers */ + ITMASK = PAGE(0) | 28, + ITSTATREG = PAGE(0) | 27, /* both pages! */ + PAGEREG = PAGE(0) | 1, /* both pages! */ + /* Baseband Codec (BBC) Registers */ + BULIOFF = PAGE(1) | 2, + BULQOFF = PAGE(1) | 3, + BULIDAC = PAGE(1) | 5, + BULQDAC = PAGE(1) | 4, + BULGCAL = PAGE(1) | 14, + BULDATA1 = PAGE(0) | 3, /* 16 words */ + BBCTRL = PAGE(1) | 6, + /* Voiceband Codec (VBC) Registers */ + VBCTRL1 = PAGE(1) | 8, + VBCTRL2 = PAGE(1) | 11, + VBPOP = PAGE(1) | 10, + VBUCTRL = PAGE(1) | 7, + VBDCTRL = PAGE(0) | 6, +}; +#define BULDATA2 BULDATA1 + +/* available ADC inputs on IOTA */ +enum twl3025_dac_inputs {/* === Signal ============================= */ + MADC_VBAT=0, /* battery voltage / 4 */ + MADC_VCHG=1, /* charger voltage / 5 */ + MADC_ICHG=2, /* I-sense amp or CHGREG DAC output */ + MADC_VBKP=3, /* backup battery voltage / 4 */ + MADC_ADIN1=4, /* VADCID, sense battery type, not used */ + MADC_ADIN2=5, /* Temperature sensor in Battery */ + MADC_ADIN3=6, /* Mode_detect: sense 2.5mm jack insertion */ + MADC_ADIN4=7, /* RITA: TEMP_SEN */ + MADC_NUM_CHANNELS=8 +}; + +enum madcstat_reg_bits { /* monitoring ADC status register */ + ADCBUSY = 0x01 /* if set, a conversion is currently going on */ +}; + +/* BCICTL1 register bits */ +enum bcictl1_reg_bits { + MESBAT = 1<<0, /* connect resistive divider for bat voltage */ + DACNBUF = 1<<1, /* bypass DAC buffer */ + THSENS0 = 1<<3, /* thermal sensor bias current (ADIN2), bit 0 */ + THSENS1 = 1<<4, /* "" bit 1 */ + THSENS2 = 1<<5, /* "" bit 2 */ + THEN = 1<<6, /* enable thermal sensor bias current (ADIN1) */ + TYPEN = 1<<7 /* enable bias current for battery type reading */ +}; + +/* BCICTL1 register bits */ +enum bcictl2_reg_bits { + CHEN = 1<<0, /* enable charger */ + CHIV = 1<<1, /* 1=constant current, 0=constant voltage */ + CHBPASSPA=1<<2, /* full charging of the battery during pulse radio */ + CLIB = 1<<3, /* calibrate I-to-V amp (short input pins) */ + CHDISPA = 1<<4, /* disabel charging during pulse radio (???) */ + LEDC = 1<<5, /* enable LED during charge */ + CGAIN4 = 1<<6, /* if set, I-to-V amp gain is reduced from 10 to 4 */ + PREOFF = 1<<7 /* disable battery precharge */ +}; + +enum vrpcsts_reg_bits { + ONBSTS = 1<<0, /* button push switched on the mobile */ + ONRSTS = 1<<1, /* RPWON terminal switched on the mobile */ + ITWSTS = 1<<2, /* ITWAKEUP terminal switched on the mobile */ + CHGSTS = 1<<3, /* plugging in charger has switched on the mobile */ + ONREFLT= 1<<4, /* state of PWON terminal after debouncing */ + ONMRFLT= 1<<5, /* state of RPWON terminal after debouncing */ + CHGPRES= 1<<6 /* charger is connected */ +}; + +enum togbr2_bits { + TOGBR2_KEEPR = (1 << 0), /* Clear KEEPON bit */ + TOGBR2_KEEPS = (1 << 1), /* Set KEEPON bit */ + TOGBR2_ACTR = (1 << 2), /* Dectivate MCLK */ + TOGBR2_ACTS = (1 << 3), /* Activate MCLK */ + TOGBR2_IBUFPTR1 = (1 << 4), /* Initialize pointer of burst buffer 1 */ + TOGBR2_IBUFPTR2 = (1 << 5), /* Initialize pointer of burst buffer 2 */ + TOGBR2_IAPCPTR = (1 << 6), /* Initialize pointer of APC RAM */ +}; + +/* How a RAMP value is encoded */ +#define ABB_RAMP_VAL(up, down) ( ((down & 0x1F) << 5) | (up & 0x1F) ) + +enum twl3025_unit { + TWL3025_UNIT_AFC, + TWL3025_UNIT_MAD, + TWL3025_UNIT_ADA, + TWL3025_UNIT_VDL, + TWL3025_UNIT_VUL, +}; + +enum twl3025_tsp_bits { + BULON = 0x80, + BULCAL = 0x40, + BULENA = 0x20, + BDLON = 0x10, + BDLCAL = 0x08, + BDLENA = 0x04, + STARTADC = 0x02, +}; + +#endif diff -r 821a26f90968 -r e60aecf23970 target-utils/libcommon/Makefile --- a/target-utils/libcommon/Makefile Tue Jun 10 20:59:32 2014 +0000 +++ b/target-utils/libcommon/Makefile Wed Jun 11 06:50:46 2014 +0000 @@ -6,7 +6,7 @@ OBJS= cmdentry.o dispatch.o hexarg.o parseargs.o serio.o serflush.o uartsel.o\ cmd_baud_switch.o cmd_dieid.o cmd_jump.o cmd_r8.o cmd_r16.o cmd_r32.o \ - cmd_w8.o cmd_w16.o cmd_w32.o osmodelay.o + cmd_w8.o cmd_w16.o cmd_w32.o abbcmd.o abbdrv.o osmodelay.o spidrv.o all: libcommon.a diff -r 821a26f90968 -r e60aecf23970 target-utils/libcommon/abbcmd.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libcommon/abbcmd.c Wed Jun 11 06:50:46 2014 +0000 @@ -0,0 +1,49 @@ +/* + * abbr pg reg -- read ABB register + * abbw pg reg val -- write ABB register + */ + +#include +#include "types.h" +#include "abbdefs.h" + +extern u16 abb_reg_read(); +extern void abb_reg_write(); + +void +cmd_abbr(argbulk) + char *argbulk; +{ + char *argv[3]; + u32 pg, reg, val; + + if (parse_args(argbulk, 2, 2, argv, 0) < 0) + return; + pg = strtoul(argv[0], 0, 0); + reg = strtoul(argv[1], 0, 0); + if (pg > 1 || reg > 31) { + printf("ERROR: argument(s) out of range\n"); + return; + } + val = abb_reg_read(PAGE(pg) | reg); + printf("%03X\n", val); +} + +void +cmd_abbw(argbulk) + char *argbulk; +{ + char *argv[4]; + u32 pg, reg, val; + + if (parse_args(argbulk, 3, 3, argv, 0) < 0) + return; + pg = strtoul(argv[0], 0, 0); + reg = strtoul(argv[1], 0, 0); + val = strtoul(argv[2], 0, 16); + if (pg > 1 || reg > 31 || val > 0x3FF) { + printf("ERROR: argument(s) out of range\n"); + return; + } + abb_reg_write(PAGE(pg) | reg, val); +} diff -r 821a26f90968 -r e60aecf23970 target-utils/libcommon/abbdrv.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libcommon/abbdrv.c Wed Jun 11 06:50:46 2014 +0000 @@ -0,0 +1,101 @@ +/* Driver for Analog Baseband Circuit (TWL3025) */ +/* lifted from OsmocomBB and ported to FreeCalypso target-utils environment */ + +/* (C) 2010 by Harald Welte + * + * 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(); + abb_reg_write(VRPCDEV, 0x01); +} diff -r 821a26f90968 -r e60aecf23970 target-utils/libcommon/spidrv.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libcommon/spidrv.c Wed Jun 11 06:50:46 2014 +0000 @@ -0,0 +1,139 @@ +/* Driver for SPI Master Controller inside TI Calypso */ +/* lifted from OsmocomBB and ported to FreeCalypso target-utils environment */ + +/* (C) 2010 by Harald Welte + * + * 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" + +#define ASIC_CONF_REG (*(volatile u16 *) 0xFFFEF008) + +struct spi_regs { + u16 reg_set1; + u16 reg_set2; + u16 reg_ctrl; + u16 reg_status; + u16 reg_tx_lsb; + u16 reg_tx_msb; + u16 reg_rx_lsb; + u16 reg_rx_msb; +}; + +#define SPI_REGS (*(volatile struct spi_regs *) 0xFFFE3000) + +#define BASE_ADDR_SPI 0xfffe3000 +#define SPI_REG(n) (BASE_ADDR_SPI+(n)) + +#define SPI_SET1_EN_CLK (1 << 0) +#define SPI_SET1_WR_IRQ_DIS (1 << 4) +#define SPI_SET1_RDWR_IRQ_DIS (1 << 5) + +#define SPI_CTRL_RDWR (1 << 0) +#define SPI_CTRL_WR (1 << 1) +#define SPI_CTRL_NB_SHIFT 2 +#define SPI_CTRL_AD_SHIFT 7 + +#define SPI_STATUS_RE (1 << 0) /* Read End */ +#define SPI_STATUS_WE (1 << 1) /* Write End */ + +spi_init() +{ + static int initdone; + + if (initdone) + return(0); + ASIC_CONF_REG |= 0x6000; + SPI_REGS.reg_set1 = SPI_SET1_EN_CLK | SPI_SET1_WR_IRQ_DIS | + SPI_SET1_RDWR_IRQ_DIS; + SPI_REGS.reg_set2 = 0x0001; + initdone = 1; + return(1); +} + +spi_xfer(dev_idx, bitlen, dout, din) + void *dout, *din; +{ + int bytes_per_xfer; + u16 reg_status, reg_ctrl = 0; + u32 tmp; + + if (bitlen <= 0) + return 0; + + if (bitlen > 32) + return -1; + + if (dev_idx > 4) + return -1; + + bytes_per_xfer = bitlen / 8; + if (bitlen % 8) + bytes_per_xfer ++; + + reg_ctrl |= (bitlen - 1) << SPI_CTRL_NB_SHIFT; + reg_ctrl |= (dev_idx & 0x7) << SPI_CTRL_AD_SHIFT; + + if (bitlen <= 8) { + tmp = *(u8 *)dout; + tmp <<= 24 + (8-bitlen); /* align to MSB */ + } else if (bitlen <= 16) { + tmp = *(u16 *)dout; + tmp <<= 16 + (16-bitlen); /* align to MSB */ + } else { + tmp = *(u32 *)dout; + tmp <<= (32-bitlen); /* align to MSB */ + } + + /* fill transmit registers */ + SPI_REGS.reg_tx_msb = tmp >> 16; + SPI_REGS.reg_tx_lsb = tmp; + + /* initiate transfer */ + if (din) + reg_ctrl |= SPI_CTRL_RDWR; + else + reg_ctrl |= SPI_CTRL_WR; + SPI_REGS.reg_ctrl = reg_ctrl; + + /* wait until the transfer is complete */ + while (1) { + reg_status = SPI_REGS.reg_status; + if (din && (reg_status & SPI_STATUS_RE)) + break; + else if (reg_status & SPI_STATUS_WE) + break; + } + /* FIXME: calibrate how much delay we really need (seven 13MHz cycles) */ + osmo_delay_ms(1); + + if (din) { + tmp = SPI_REGS.reg_rx_msb << 16; + tmp |= SPI_REGS.reg_rx_lsb; + + if (bitlen <= 8) + *(u8 *)din = tmp & 0xff; + else if (bitlen <= 16) + *(u16 *)din = tmp & 0xffff; + else + *(u32 *)din = tmp; + } + + return 0; +} diff -r 821a26f90968 -r e60aecf23970 target-utils/pirexplore/cmdtab.c --- a/target-utils/pirexplore/cmdtab.c Tue Jun 10 20:59:32 2014 +0000 +++ b/target-utils/pirexplore/cmdtab.c Wed Jun 11 06:50:46 2014 +0000 @@ -1,5 +1,7 @@ #include "cmdtab.h" +extern void cmd_abbr(); +extern void cmd_abbw(); extern void cmd_baud_switch(); extern void cmd_blit(); extern void cmd_dieid(); @@ -20,10 +22,15 @@ extern void cmd_w16(); extern void cmd_w32(); +extern void abb_init(); +extern void abb_power_off(); extern void cmd_memdump_human(); extern void mpffs_init(); const struct cmdtab cmdtab[] = { + {"abbinit", abb_init}, + {"abbr", cmd_abbr}, + {"abbw", cmd_abbw}, {"baud", cmd_baud_switch}, {"blit", cmd_blit}, {"dieid", cmd_dieid}, @@ -35,6 +42,7 @@ {"lcdfill", cmd_lcdfill}, {"lcdinit", cmd_lcdinit}, {"lcdtest", cmd_lcdtest}, + {"poweroff", abb_power_off}, {"r8", cmd_r8}, {"r16", cmd_r16}, {"r32", cmd_r32},