/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c
C | 302 lines | 218 code | 35 blank | 49 comment | 14 complexity | 50b3ad0b7c54a63067255e15333d9b2c MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
1/* 2* Customer code to add GPIO control during WLAN start/stop 3* Copyright (C) 1999-2011, Broadcom Corporation 4* 5* Unless you and Broadcom execute a separate written software license 6* agreement governing use of this software, this software is licensed to you 7* under the terms of the GNU General Public License version 2 (the "GPL"), 8* available at http://www.broadcom.com/licenses/GPLv2.php, with the 9* following added to such license: 10* 11* As a special exception, the copyright holders of this software give you 12* permission to link this software with independent modules, and to copy and 13* distribute the resulting executable under terms of your choice, provided that 14* you also meet, for each linked independent module, the terms and conditions of 15* the license of that module. An independent module is a module which is not 16* derived from this software. The special exception does not apply to any 17* modifications of the software. 18* 19* Notwithstanding the above, under no circumstances may you combine this 20* software in any way with any other Broadcom software provided under a license 21* other than the GPL, without Broadcom's express prior written consent. 22* 23* $Id: dhd_custom_gpio.c,v 1.2.42.1 2010-10-19 00:41:09 Exp $ 24*/ 25 26#include <typedefs.h> 27#include <linuxver.h> 28#include <osl.h> 29#include <bcmutils.h> 30 31#include <dngl_stats.h> 32#include <dhd.h> 33 34#include <wlioctl.h> 35#include <wl_iw.h> 36 37#define WL_ERROR(x) printf x 38#define WL_TRACE(x) 39 40#ifdef CUSTOMER_HW 41extern void bcm_wlan_power_off(int); 42extern void bcm_wlan_power_on(int); 43#endif /* CUSTOMER_HW */ 44#if defined(CUSTOMER_HW2) 45#ifdef CONFIG_WIFI_CONTROL_FUNC 46int wifi_set_power(int on, unsigned long msec); 47int wifi_get_irq_number(unsigned long *irq_flags_ptr); 48int wifi_get_mac_addr(unsigned char *buf); 49void *wifi_get_country_code(char *ccode); 50#else 51int wifi_set_power(int on, unsigned long msec) { return -1; } 52int wifi_get_irq_number(unsigned long *irq_flags_ptr) { return -1; } 53int wifi_get_mac_addr(unsigned char *buf) { return -1; } 54void *wifi_get_country_code(char *ccode) { return NULL; } 55#endif /* CONFIG_WIFI_CONTROL_FUNC */ 56#endif /* CUSTOMER_HW2 */ 57 58#if defined(OOB_INTR_ONLY) 59 60#if defined(BCMLXSDMMC) 61extern int sdioh_mmc_irq(int irq); 62#endif /* (BCMLXSDMMC) */ 63 64#ifdef CUSTOMER_HW3 65#include <mach/gpio.h> 66#endif 67 68/* Customer specific Host GPIO defintion */ 69static int dhd_oob_gpio_num = -1; 70 71module_param(dhd_oob_gpio_num, int, 0644); 72MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number"); 73 74/* This function will return: 75 * 1) return : Host gpio interrupt number per customer platform 76 * 2) irq_flags_ptr : Type of Host interrupt as Level or Edge 77 * 78 * NOTE : 79 * Customer should check his platform definitions 80 * and his Host Interrupt spec 81 * to figure out the proper setting for his platform. 82 * Broadcom provides just reference settings as example. 83 * 84 */ 85int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr) 86{ 87 int host_oob_irq = 0; 88 89#ifdef CUSTOMER_HW2 90 host_oob_irq = wifi_get_irq_number(irq_flags_ptr); 91 92#else 93#if defined(CUSTOM_OOB_GPIO_NUM) 94 if (dhd_oob_gpio_num < 0) { 95 dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM; 96 } 97#endif /* CUSTOMER_HW2 */ 98 99 if (dhd_oob_gpio_num < 0) { 100 WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined \n", 101 __FUNCTION__)); 102 return (dhd_oob_gpio_num); 103 } 104 105 WL_ERROR(("%s: customer specific Host GPIO number is (%d)\n", 106 __FUNCTION__, dhd_oob_gpio_num)); 107 108#if defined CUSTOMER_HW 109 host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num); 110#elif defined CUSTOMER_HW3 111 gpio_request(dhd_oob_gpio_num, "oob irq"); 112 host_oob_irq = gpio_to_irq(dhd_oob_gpio_num); 113 gpio_direction_input(dhd_oob_gpio_num); 114#endif /* CUSTOMER_HW */ 115#endif /* CUSTOMER_HW2 */ 116 117 return (host_oob_irq); 118} 119#endif /* defined(OOB_INTR_ONLY) */ 120 121/* Customer function to control hw specific wlan gpios */ 122void 123dhd_customer_gpio_wlan_ctrl(int onoff) 124{ 125 switch (onoff) { 126 case WLAN_RESET_OFF: 127 WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", 128 __FUNCTION__)); 129#ifdef CUSTOMER_HW 130 bcm_wlan_power_off(2); 131#endif /* CUSTOMER_HW */ 132#ifdef CUSTOMER_HW2 133 wifi_set_power(0, 0); 134#endif 135 WL_ERROR(("=========== WLAN placed in RESET ========\n")); 136 break; 137 138 case WLAN_RESET_ON: 139 WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", 140 __FUNCTION__)); 141#ifdef CUSTOMER_HW 142 bcm_wlan_power_on(2); 143#endif /* CUSTOMER_HW */ 144#ifdef CUSTOMER_HW2 145 wifi_set_power(1, 0); 146#endif 147 WL_ERROR(("=========== WLAN going back to live ========\n")); 148 break; 149 150 case WLAN_POWER_OFF: 151 WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", 152 __FUNCTION__)); 153#ifdef CUSTOMER_HW 154 bcm_wlan_power_off(1); 155#endif /* CUSTOMER_HW */ 156 break; 157 158 case WLAN_POWER_ON: 159 WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", 160 __FUNCTION__)); 161#ifdef CUSTOMER_HW 162 bcm_wlan_power_on(1); 163 /* Lets customer power to get stable */ 164 OSL_DELAY(200); 165#endif /* CUSTOMER_HW */ 166 break; 167 } 168} 169 170#ifdef GET_CUSTOM_MAC_ENABLE 171/* Function to get custom MAC address */ 172int 173dhd_custom_get_mac_address(unsigned char *buf) 174{ 175 int ret = 0; 176 177 WL_TRACE(("%s Enter\n", __FUNCTION__)); 178 if (!buf) 179 return -EINVAL; 180 181 /* Customer access to MAC address stored outside of DHD driver */ 182#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) 183 ret = wifi_get_mac_addr(buf); 184#endif 185 186#ifdef EXAMPLE_GET_MAC 187 /* EXAMPLE code */ 188 { 189 struct ether_addr ea_example = {{0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}}; 190 bcopy((char *)&ea_example, buf, sizeof(struct ether_addr)); 191 } 192#endif /* EXAMPLE_GET_MAC */ 193 194 return ret; 195} 196#endif /* GET_CUSTOM_MAC_ENABLE */ 197 198#define EXAMPLE_TABLE 199/* Customized Locale table : OPTIONAL feature */ 200const struct cntry_locales_custom translate_custom_table[] = { 201/* Table should be filled out based on custom platform regulatory requirement */ 202#ifdef EXAMPLE_TABLE 203 {"", "XY", 4}, /* Universal if Country code is unknown or empty */ 204 {"EU", "EU", 5}, /* European union countries to : EU regrev 05 */ 205 {"AT", "EU", 5}, 206 {"BE", "EU", 5}, 207 {"BG", "EU", 5}, 208 {"CY", "EU", 5}, 209 {"CZ", "EU", 5}, 210 {"DK", "EU", 5}, 211 {"EE", "EU", 5}, 212 {"FI", "EU", 5}, 213 {"FR", "EU", 5}, 214 {"DE", "EU", 5}, 215 {"GR", "EU", 5}, 216 {"HU", "EU", 5}, 217 {"IE", "EU", 5}, 218 {"IT", "EU", 5}, 219 {"LV", "EU", 5}, 220 {"LI", "EU", 5}, 221 {"LT", "EU", 5}, 222 {"LU", "EU", 5}, 223 {"MT", "EU", 5}, 224 {"NL", "EU", 5}, 225 {"PL", "EU", 5}, 226 {"PT", "EU", 5}, 227 {"RO", "EU", 5}, 228 {"SK", "EU", 5}, 229 {"SI", "EU", 5}, 230 {"ES", "EU", 5}, 231 {"SE", "EU", 5}, 232 {"GB", "EU", 5}, 233 {"IL", "IL", 0}, 234 {"CH", "CH", 0}, 235 {"TR", "TR", 0}, 236 {"NO", "NO", 0}, 237 {"KR", "XY", 4}, 238 {"AU", "XY", 4}, 239 {"CN", "XY", 4}, /* input ISO "CN" to : XY regrev 03 */ 240 {"AR", "XY", 4}, 241 {"MX", "XY", 4}, 242 {"AS", "US", 69}, 243 {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */ 244 {"KY", "US", 69}, 245 {"GU", "US", 69}, 246 {"FM", "US", 69}, 247 {"MP", "US", 69}, 248 {"PR", "US", 69}, 249 {"TW", "US", 69}, 250 {"VI", "US", 69}, 251 {"UM", "US", 69}, 252 {"US", "US", 69} /* input ISO "US" to : US regrev 69 */ 253#endif /* EXAMPLE_TABLE */ 254}; 255 256 257/* Customized Locale convertor 258* input : ISO 3166-1 country abbreviation 259* output: customized cspec 260*/ 261void get_customized_country_code(char *country_iso_code, wl_country_t *cspec) 262{ 263//#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) 264#if 0 // Use Broadcom country code table 265 struct cntry_locales_custom *cloc_ptr; 266 267 if (!cspec) 268 return; 269 270 cloc_ptr = wifi_get_country_code(country_iso_code); 271 if (cloc_ptr) { 272 strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ); 273 cspec->rev = cloc_ptr->custom_locale_rev; 274 } 275 return; 276#else 277 int size, i; 278 279 size = ARRAYSIZE(translate_custom_table); 280 281 if (cspec == 0) 282 return; 283 284 if (size == 0) 285 return; 286 287 for (i = 0; i < size; i++) { 288 if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) { 289 memcpy(cspec->ccode, 290 translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ); 291 cspec->rev = translate_custom_table[i].custom_locale_rev; 292 return; 293 } 294 } 295#ifdef EXAMPLE_TABLE 296 /* if no country code matched return first universal code from translate_custom_table */ 297 memcpy(cspec->ccode, translate_custom_table[0].custom_locale, WLC_CNTRY_BUF_SZ); 298 cspec->rev = translate_custom_table[0].custom_locale_rev; 299#endif /* EXAMPLE_TABLE */ 300 return; 301#endif /* defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */ 302}