Home | History | Annotate | Download | only in ath5k
      1 /*
      2  * Copyright (c) 2004-2008 Reyk Floeter <reyk (at) openbsd.org>
      3  * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm (at) gmail.com>
      4  *
      5  * Lightly modified for gPXE, July 2009, by Joshua Oreman <oremanj (at) rwcr.net>.
      6  *
      7  * Permission to use, copy, modify, and distribute this software for any
      8  * purpose with or without fee is hereby granted, provided that the above
      9  * copyright notice and this permission notice appear in all copies.
     10  *
     11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18  *
     19  */
     20 
     21 FILE_LICENCE ( MIT );
     22 
     23 /****************\
     24   GPIO Functions
     25 \****************/
     26 
     27 #include "ath5k.h"
     28 #include "reg.h"
     29 #include "base.h"
     30 
     31 /*
     32  * Set GPIO inputs
     33  */
     34 int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
     35 {
     36 	if (gpio >= AR5K_NUM_GPIO)
     37 		return -EINVAL;
     38 
     39 	ath5k_hw_reg_write(ah,
     40 		(ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
     41 		| AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
     42 
     43 	return 0;
     44 }
     45 
     46 /*
     47  * Set GPIO outputs
     48  */
     49 int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
     50 {
     51 	if (gpio >= AR5K_NUM_GPIO)
     52 		return -EINVAL;
     53 
     54 	ath5k_hw_reg_write(ah,
     55 		(ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
     56 		| AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
     57 
     58 	return 0;
     59 }
     60 
     61 /*
     62  * Get GPIO state
     63  */
     64 u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
     65 {
     66 	if (gpio >= AR5K_NUM_GPIO)
     67 		return 0xffffffff;
     68 
     69 	/* GPIO input magic */
     70 	return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
     71 		0x1;
     72 }
     73 
     74 /*
     75  * Set GPIO state
     76  */
     77 int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
     78 {
     79 	u32 data;
     80 
     81 	if (gpio >= AR5K_NUM_GPIO)
     82 		return -EINVAL;
     83 
     84 	/* GPIO output magic */
     85 	data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
     86 
     87 	data &= ~(1 << gpio);
     88 	data |= (val & 1) << gpio;
     89 
     90 	ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
     91 
     92 	return 0;
     93 }
     94 
     95 /*
     96  * Initialize the GPIO interrupt (RFKill switch)
     97  */
     98 void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
     99 		u32 interrupt_level)
    100 {
    101 	u32 data;
    102 
    103 	if (gpio >= AR5K_NUM_GPIO)
    104 		return;
    105 
    106 	/*
    107 	 * Set the GPIO interrupt
    108 	 */
    109 	data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
    110 		~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
    111 		AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
    112 		(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
    113 
    114 	ath5k_hw_reg_write(ah, interrupt_level ? data :
    115 		(data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
    116 
    117 	ah->ah_imr |= AR5K_IMR_GPIO;
    118 
    119 	/* Enable GPIO interrupts */
    120 	AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
    121 }
    122 
    123