ar5212_gpio.c revision 185377
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 * 17185377Ssam * $Id: ar5212_gpio.c,v 1.3 2008/11/10 04:08:03 sam Exp $ 18185377Ssam */ 19185377Ssam#include "opt_ah.h" 20185377Ssam 21185377Ssam#ifdef AH_SUPPORT_AR5212 22185377Ssam 23185377Ssam#include "ah.h" 24185377Ssam#include "ah_internal.h" 25185377Ssam#include "ah_devid.h" 26185377Ssam#ifdef AH_DEBUG 27185377Ssam#include "ah_desc.h" /* NB: for HAL_PHYERR* */ 28185377Ssam#endif 29185377Ssam 30185377Ssam#include "ar5212/ar5212.h" 31185377Ssam#include "ar5212/ar5212reg.h" 32185377Ssam#include "ar5212/ar5212phy.h" 33185377Ssam#ifdef AH_SUPPORT_AR5311 34185377Ssam#include "ar5212/ar5311reg.h" 35185377Ssam#endif 36185377Ssam 37185377Ssam#define AR_NUM_GPIO 6 /* 6 GPIO pins */ 38185377Ssam#define AR_GPIOD_MASK 0x0000002F /* GPIO data reg r/w mask */ 39185377Ssam 40185377Ssam/* 41185377Ssam * Configure GPIO Output lines 42185377Ssam */ 43185377SsamHAL_BOOL 44185377Ssamar5212GpioCfgOutput(struct ath_hal *ah, uint32_t gpio) 45185377Ssam{ 46185377Ssam HALASSERT(gpio < AR_NUM_GPIO); 47185377Ssam 48185377Ssam /* 49185377Ssam * NB: AR_GPIOCR_CR_A(pin) is all 1's so there's no need 50185377Ssam * to clear the field before or'ing in the new value. 51185377Ssam */ 52185377Ssam OS_REG_WRITE(ah, AR_GPIOCR, 53185377Ssam OS_REG_READ(ah, AR_GPIOCR) | AR_GPIOCR_CR_A(gpio)); 54185377Ssam 55185377Ssam return AH_TRUE; 56185377Ssam} 57185377Ssam 58185377Ssam/* 59185377Ssam * Configure GPIO Input lines 60185377Ssam */ 61185377SsamHAL_BOOL 62185377Ssamar5212GpioCfgInput(struct ath_hal *ah, uint32_t gpio) 63185377Ssam{ 64185377Ssam HALASSERT(gpio < AR_NUM_GPIO); 65185377Ssam 66185377Ssam OS_REG_WRITE(ah, AR_GPIOCR, 67185377Ssam (OS_REG_READ(ah, AR_GPIOCR) &~ AR_GPIOCR_CR_A(gpio)) 68185377Ssam | AR_GPIOCR_CR_N(gpio)); 69185377Ssam 70185377Ssam return AH_TRUE; 71185377Ssam} 72185377Ssam 73185377Ssam/* 74185377Ssam * Once configured for I/O - set output lines 75185377Ssam */ 76185377SsamHAL_BOOL 77185377Ssamar5212GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val) 78185377Ssam{ 79185377Ssam uint32_t reg; 80185377Ssam 81185377Ssam HALASSERT(gpio < AR_NUM_GPIO); 82185377Ssam 83185377Ssam reg = OS_REG_READ(ah, AR_GPIODO); 84185377Ssam reg &= ~(1 << gpio); 85185377Ssam reg |= (val&1) << gpio; 86185377Ssam 87185377Ssam OS_REG_WRITE(ah, AR_GPIODO, reg); 88185377Ssam return AH_TRUE; 89185377Ssam} 90185377Ssam 91185377Ssam/* 92185377Ssam * Once configured for I/O - get input lines 93185377Ssam */ 94185377Ssamuint32_t 95185377Ssamar5212GpioGet(struct ath_hal *ah, uint32_t gpio) 96185377Ssam{ 97185377Ssam if (gpio < AR_NUM_GPIO) { 98185377Ssam uint32_t val = OS_REG_READ(ah, AR_GPIODI); 99185377Ssam val = ((val & AR_GPIOD_MASK) >> gpio) & 0x1; 100185377Ssam return val; 101185377Ssam } else { 102185377Ssam return 0xffffffff; 103185377Ssam } 104185377Ssam} 105185377Ssam 106185377Ssam/* 107185377Ssam * Set the GPIO Interrupt 108185377Ssam */ 109185377Ssamvoid 110185377Ssamar5212GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel) 111185377Ssam{ 112185377Ssam uint32_t val; 113185377Ssam 114185377Ssam /* XXX bounds check gpio */ 115185377Ssam val = OS_REG_READ(ah, AR_GPIOCR); 116185377Ssam val &= ~(AR_GPIOCR_CR_A(gpio) | 117185377Ssam AR_GPIOCR_INT_MASK | AR_GPIOCR_INT_ENA | AR_GPIOCR_INT_SEL); 118185377Ssam val |= AR_GPIOCR_CR_N(gpio) | AR_GPIOCR_INT(gpio) | AR_GPIOCR_INT_ENA; 119185377Ssam if (ilevel) 120185377Ssam val |= AR_GPIOCR_INT_SELH; /* interrupt on pin high */ 121185377Ssam else 122185377Ssam val |= AR_GPIOCR_INT_SELL; /* interrupt on pin low */ 123185377Ssam 124185377Ssam /* Don't need to change anything for low level interrupt. */ 125185377Ssam OS_REG_WRITE(ah, AR_GPIOCR, val); 126185377Ssam 127185377Ssam /* Change the interrupt mask. */ 128185377Ssam (void) ar5212SetInterrupts(ah, AH5212(ah)->ah_maskReg | HAL_INT_GPIO); 129185377Ssam} 130185377Ssam 131185377Ssam#endif /* AH_SUPPORT_AR5212 */ 132