• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3  * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4  *
5  * Lightly modified for gPXE, July 2009, by Joshua Oreman <oremanj@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  */
ath5k_hw_set_gpio_input(struct ath5k_hw * ah,u32 gpio)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  */
ath5k_hw_set_gpio_output(struct ath5k_hw * ah,u32 gpio)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  */
ath5k_hw_get_gpio(struct ath5k_hw * ah,u32 gpio)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  */
ath5k_hw_set_gpio(struct ath5k_hw * ah,u32 gpio,u32 val)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  */
ath5k_hw_set_gpio_intr(struct ath5k_hw * ah,unsigned int gpio,u32 interrupt_level)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