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#if (AH_SUPPORT_2316 || AH_SUPPORT_2317) 22185377Ssam 23185377Ssam#include "ah.h" 24185377Ssam#include "ah_internal.h" 25185377Ssam#include "ah_devid.h" 26185377Ssam 27185377Ssam#include "ar5312/ar5312.h" 28185377Ssam#include "ar5312/ar5312reg.h" 29185377Ssam#include "ar5312/ar5312phy.h" 30185377Ssam 31185377Ssam#define AR_NUM_GPIO 7 /* 6 GPIO pins */ 32185377Ssam#define AR5315_GPIOD_MASK 0x0000007F /* GPIO data reg r/w mask */ 33185377Ssam 34185377Ssam/* 35185377Ssam * Configure GPIO Output lines 36185377Ssam */ 37185377SsamHAL_BOOL 38188974Ssamar5315GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE type) 39185377Ssam{ 40185377Ssam uint32_t gpioOffset = (AR5315_GPIO_BASE - ((uint32_t) ah->ah_sh)); 41185377Ssam 42185377Ssam HALASSERT(gpio < AR_NUM_GPIO); 43185377Ssam 44185377Ssam OS_REG_WRITE(ah, gpioOffset+AR5315_GPIODIR, 45185377Ssam (OS_REG_READ(ah, gpioOffset+AR5315_GPIODIR) &~ AR5315_GPIODIR_M(gpio)) 46185377Ssam | AR5315_GPIODIR_O(gpio)); 47185377Ssam 48185377Ssam return AH_TRUE; 49185377Ssam} 50185377Ssam 51185377Ssam/* 52185377Ssam * Configure GPIO Input lines 53185377Ssam */ 54185377SsamHAL_BOOL 55185377Ssamar5315GpioCfgInput(struct ath_hal *ah, uint32_t gpio) 56185377Ssam{ 57185377Ssam uint32_t gpioOffset = (AR5315_GPIO_BASE - ((uint32_t) ah->ah_sh)); 58185377Ssam 59185377Ssam HALASSERT(gpio < AR_NUM_GPIO); 60185377Ssam 61185377Ssam OS_REG_WRITE(ah, gpioOffset+AR5315_GPIODIR, 62185377Ssam (OS_REG_READ(ah, gpioOffset+AR5315_GPIODIR) &~ AR5315_GPIODIR_M(gpio)) 63185377Ssam | AR5315_GPIODIR_I(gpio)); 64185377Ssam 65185377Ssam return AH_TRUE; 66185377Ssam} 67185377Ssam 68185377Ssam/* 69185377Ssam * Once configured for I/O - set output lines 70185377Ssam */ 71185377SsamHAL_BOOL 72185377Ssamar5315GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val) 73185377Ssam{ 74185377Ssam uint32_t reg; 75185377Ssam uint32_t gpioOffset = (AR5315_GPIO_BASE - ((uint32_t) ah->ah_sh)); 76185377Ssam 77185377Ssam HALASSERT(gpio < AR_NUM_GPIO); 78185377Ssam 79185377Ssam reg = OS_REG_READ(ah, gpioOffset+AR5315_GPIODO); 80185377Ssam reg &= ~(1 << gpio); 81185377Ssam reg |= (val&1) << gpio; 82185377Ssam 83185377Ssam OS_REG_WRITE(ah, gpioOffset+AR5315_GPIODO, reg); 84185377Ssam return AH_TRUE; 85185377Ssam} 86185377Ssam 87185377Ssam/* 88185377Ssam * Once configured for I/O - get input lines 89185377Ssam */ 90185377Ssamuint32_t 91185377Ssamar5315GpioGet(struct ath_hal *ah, uint32_t gpio) 92185377Ssam{ 93185377Ssam uint32_t gpioOffset = (AR5315_GPIO_BASE - ((uint32_t) ah->ah_sh)); 94185377Ssam 95185377Ssam if (gpio < AR_NUM_GPIO) { 96185377Ssam uint32_t val = OS_REG_READ(ah, gpioOffset+AR5315_GPIODI); 97185377Ssam val = ((val & AR5315_GPIOD_MASK) >> gpio) & 0x1; 98185377Ssam return val; 99185377Ssam } else { 100185377Ssam return 0xffffffff; 101185377Ssam } 102185377Ssam} 103185377Ssam 104185377Ssam/* 105185377Ssam * Set the GPIO Interrupt 106185377Ssam */ 107185377Ssamvoid 108185377Ssamar5315GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel) 109185377Ssam{ 110185377Ssam uint32_t val; 111185377Ssam uint32_t gpioOffset = (AR5315_GPIO_BASE - ((uint32_t) ah->ah_sh)); 112185377Ssam 113185377Ssam /* XXX bounds check gpio */ 114185377Ssam val = OS_REG_READ(ah, gpioOffset+AR5315_GPIOINT); 115185377Ssam val &= ~(AR5315_GPIOINT_M | AR5315_GPIOINTLVL_M); 116185377Ssam val |= gpio << AR5315_GPIOINT_S; 117185377Ssam if (ilevel) 118185377Ssam val |= 2 << AR5315_GPIOINTLVL_S; /* interrupt on pin high */ 119185377Ssam else 120185377Ssam val |= 1 << AR5315_GPIOINTLVL_S; /* interrupt on pin low */ 121185377Ssam 122185377Ssam /* Don't need to change anything for low level interrupt. */ 123185377Ssam OS_REG_WRITE(ah, gpioOffset+AR5315_GPIOINT, val); 124185377Ssam 125185377Ssam /* Change the interrupt mask. */ 126185377Ssam (void) ar5212SetInterrupts(ah, AH5212(ah)->ah_maskReg | HAL_INT_GPIO); 127185377Ssam} 128185377Ssam 129185377Ssam 130185377Ssam#endif /* AH_SUPPORT_2316 || AH_SUPPORT_2317 */ 131