1185377Ssam/* 2185377Ssam * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3185377Ssam * Copyright (c) 2002-2008 Atheros Communications, Inc. 4185377Ssam * 5185377Ssam * Permission to use, copy, modify, and/or distribute this software for any 6185377Ssam * purpose with or without fee is hereby granted, provided that the above 7185377Ssam * copyright notice and this permission notice appear in all copies. 8185377Ssam * 9185377Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10185377Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11185377Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12185377Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13185377Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14185377Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15185377Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16185377Ssam * 17188974Ssam * $FreeBSD$ 18185377Ssam */ 19185377Ssam#include "opt_ah.h" 20185377Ssam 21185377Ssam#include "ah.h" 22185377Ssam#include "ah_internal.h" 23185377Ssam#include "ah_devid.h" 24185377Ssam#ifdef AH_DEBUG 25185377Ssam#include "ah_desc.h" /* NB: for HAL_PHYERR* */ 26185377Ssam#endif 27185377Ssam 28185377Ssam#include "ar5212/ar5212.h" 29185377Ssam#include "ar5212/ar5212reg.h" 30185377Ssam#include "ar5212/ar5212phy.h" 31185377Ssam 32185377Ssam#define AR_NUM_GPIO 6 /* 6 GPIO pins */ 33185377Ssam#define AR_GPIOD_MASK 0x0000002F /* GPIO data reg r/w mask */ 34185377Ssam 35185377Ssam/* 36185377Ssam * Configure GPIO Output lines 37185377Ssam */ 38185377SsamHAL_BOOL 39188974Ssamar5212GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE type) 40185377Ssam{ 41185377Ssam HALASSERT(gpio < AR_NUM_GPIO); 42185377Ssam 43185377Ssam /* 44185377Ssam * NB: AR_GPIOCR_CR_A(pin) is all 1's so there's no need 45185377Ssam * to clear the field before or'ing in the new value. 46185377Ssam */ 47185377Ssam OS_REG_WRITE(ah, AR_GPIOCR, 48185377Ssam OS_REG_READ(ah, AR_GPIOCR) | AR_GPIOCR_CR_A(gpio)); 49185377Ssam 50185377Ssam return AH_TRUE; 51185377Ssam} 52185377Ssam 53185377Ssam/* 54185377Ssam * Configure GPIO Input lines 55185377Ssam */ 56185377SsamHAL_BOOL 57185377Ssamar5212GpioCfgInput(struct ath_hal *ah, uint32_t gpio) 58185377Ssam{ 59185377Ssam HALASSERT(gpio < AR_NUM_GPIO); 60185377Ssam 61185377Ssam OS_REG_WRITE(ah, AR_GPIOCR, 62185377Ssam (OS_REG_READ(ah, AR_GPIOCR) &~ AR_GPIOCR_CR_A(gpio)) 63185377Ssam | AR_GPIOCR_CR_N(gpio)); 64185377Ssam 65185377Ssam return AH_TRUE; 66185377Ssam} 67185377Ssam 68185377Ssam/* 69185377Ssam * Once configured for I/O - set output lines 70185377Ssam */ 71185377SsamHAL_BOOL 72185377Ssamar5212GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val) 73185377Ssam{ 74185377Ssam uint32_t reg; 75185377Ssam 76185377Ssam HALASSERT(gpio < AR_NUM_GPIO); 77185377Ssam 78185377Ssam reg = OS_REG_READ(ah, AR_GPIODO); 79185377Ssam reg &= ~(1 << gpio); 80185377Ssam reg |= (val&1) << gpio; 81185377Ssam 82185377Ssam OS_REG_WRITE(ah, AR_GPIODO, reg); 83185377Ssam return AH_TRUE; 84185377Ssam} 85185377Ssam 86185377Ssam/* 87185377Ssam * Once configured for I/O - get input lines 88185377Ssam */ 89185377Ssamuint32_t 90185377Ssamar5212GpioGet(struct ath_hal *ah, uint32_t gpio) 91185377Ssam{ 92185377Ssam if (gpio < AR_NUM_GPIO) { 93185377Ssam uint32_t val = OS_REG_READ(ah, AR_GPIODI); 94185377Ssam val = ((val & AR_GPIOD_MASK) >> gpio) & 0x1; 95185377Ssam return val; 96185377Ssam } else { 97185377Ssam return 0xffffffff; 98185377Ssam } 99185377Ssam} 100185377Ssam 101185377Ssam/* 102185377Ssam * Set the GPIO Interrupt 103185377Ssam */ 104185377Ssamvoid 105185377Ssamar5212GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel) 106185377Ssam{ 107185377Ssam uint32_t val; 108185377Ssam 109185377Ssam /* XXX bounds check gpio */ 110185377Ssam val = OS_REG_READ(ah, AR_GPIOCR); 111185377Ssam val &= ~(AR_GPIOCR_CR_A(gpio) | 112185377Ssam AR_GPIOCR_INT_MASK | AR_GPIOCR_INT_ENA | AR_GPIOCR_INT_SEL); 113185377Ssam val |= AR_GPIOCR_CR_N(gpio) | AR_GPIOCR_INT(gpio) | AR_GPIOCR_INT_ENA; 114185377Ssam if (ilevel) 115185377Ssam val |= AR_GPIOCR_INT_SELH; /* interrupt on pin high */ 116185377Ssam else 117185377Ssam val |= AR_GPIOCR_INT_SELL; /* interrupt on pin low */ 118185377Ssam 119185377Ssam /* Don't need to change anything for low level interrupt. */ 120185377Ssam OS_REG_WRITE(ah, AR_GPIOCR, val); 121185377Ssam 122185377Ssam /* Change the interrupt mask. */ 123185377Ssam (void) ar5212SetInterrupts(ah, AH5212(ah)->ah_maskReg | HAL_INT_GPIO); 124185377Ssam} 125