diff options
author | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
---|---|---|
committer | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
commit | c6da2cfeb05178a11c6d062a06f8078150ee492f (patch) | |
tree | f3b4021d252c52d6463a9b3c1bb7245e399b009c /arch/arm/mach-exynos/board-midas-wlan.c | |
parent | c6d7c4dbff353eac7919342ae6b3299a378160a6 (diff) | |
download | kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.zip kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.gz kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.bz2 |
samsung update 1
Diffstat (limited to 'arch/arm/mach-exynos/board-midas-wlan.c')
-rwxr-xr-x | arch/arm/mach-exynos/board-midas-wlan.c | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/arch/arm/mach-exynos/board-midas-wlan.c b/arch/arm/mach-exynos/board-midas-wlan.c new file mode 100755 index 0000000..5d9a584 --- /dev/null +++ b/arch/arm/mach-exynos/board-midas-wlan.c @@ -0,0 +1,326 @@ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/skbuff.h> +#include <linux/wlan_plat.h> + +#include <plat/devs.h> +#include <plat/sdhci.h> +#include <plat/gpio-cfg.h> +#include <mach/regs-gpio.h> +#include <mach/gpio.h> + +#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM + +#define WLAN_STATIC_SCAN_BUF0 5 +#define WLAN_STATIC_SCAN_BUF1 6 +#define PREALLOC_WLAN_SEC_NUM 4 +#define PREALLOC_WLAN_BUF_NUM 160 +#define PREALLOC_WLAN_SECTION_HEADER 24 + +#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128) +#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_BUF_NUM * 128) +#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_BUF_NUM * 512) +#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024) + +#define DHD_SKB_HDRSIZE 336 +#define DHD_SKB_1PAGE_BUFSIZE ((PAGE_SIZE*1)-DHD_SKB_HDRSIZE) +#define DHD_SKB_2PAGE_BUFSIZE ((PAGE_SIZE*2)-DHD_SKB_HDRSIZE) +#define DHD_SKB_4PAGE_BUFSIZE ((PAGE_SIZE*4)-DHD_SKB_HDRSIZE) + +#define WLAN_SKB_BUF_NUM 17 + +static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM]; + +struct wlan_mem_prealloc { + void *mem_ptr; + unsigned long size; +}; + +static struct wlan_mem_prealloc wlan_mem_array[PREALLOC_WLAN_SEC_NUM] = { + {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)}, + {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)}, + {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)}, + {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)} +}; + +void *wlan_static_scan_buf0; +void *wlan_static_scan_buf1; +static void *brcm_wlan_mem_prealloc(int section, unsigned long size) +{ + if (section == PREALLOC_WLAN_SEC_NUM) + return wlan_static_skb; + if (section == WLAN_STATIC_SCAN_BUF0) + return wlan_static_scan_buf0; + if (section == WLAN_STATIC_SCAN_BUF1) + return wlan_static_scan_buf1; + if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM)) + return NULL; + + if (wlan_mem_array[section].size < size) + return NULL; + + return wlan_mem_array[section].mem_ptr; +} + +static int brcm_init_wlan_mem(void) +{ + int i; + int j; + + for (i = 0; i < 8; i++) { + wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE); + if (!wlan_static_skb[i]) + goto err_skb_alloc; + } + + for (; i < 16; i++) { + wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE); + if (!wlan_static_skb[i]) + goto err_skb_alloc; + } + + wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE); + if (!wlan_static_skb[i]) + goto err_skb_alloc; + + for (i = 0 ; i < PREALLOC_WLAN_SEC_NUM ; i++) { + wlan_mem_array[i].mem_ptr = + kmalloc(wlan_mem_array[i].size, GFP_KERNEL); + + if (!wlan_mem_array[i].mem_ptr) + goto err_mem_alloc; + } + wlan_static_scan_buf0 = kmalloc (65536, GFP_KERNEL); + if(!wlan_static_scan_buf0) + goto err_mem_alloc; + wlan_static_scan_buf1 = kmalloc (65536, GFP_KERNEL); + if(!wlan_static_scan_buf1) + goto err_mem_alloc; + + printk("%s: WIFI MEM Allocated\n", __FUNCTION__); + return 0; + + err_mem_alloc: + pr_err("Failed to mem_alloc for WLAN\n"); + for (j = 0 ; j < i ; j++) + kfree(wlan_mem_array[j].mem_ptr); + + i = WLAN_SKB_BUF_NUM; + + err_skb_alloc: + pr_err("Failed to skb_alloc for WLAN\n"); + for (j = 0 ; j < i ; j++) + dev_kfree_skb(wlan_static_skb[j]); + + return -ENOMEM; +} +#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */ + +static unsigned int wlan_on_gpio_table[][4] = { + {GPIO_WLAN_EN , GPIO_WLAN_EN_AF, GPIO_LEVEL_HIGH, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_HOST_WAKE, GPIO_WLAN_HOST_WAKE_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN}, +}; + +static unsigned int wlan_off_gpio_table[][4] = { + {GPIO_WLAN_EN , GPIO_WLAN_EN_AF, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_HOST_WAKE, 0 , GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN}, +}; + +static unsigned int wlan_sdio_on_table[][4] = { + {GPIO_WLAN_SDIO_CLK, GPIO_WLAN_SDIO_CLK_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_SDIO_CMD, GPIO_WLAN_SDIO_CMD_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_SDIO_D0, GPIO_WLAN_SDIO_D0_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_SDIO_D1, GPIO_WLAN_SDIO_D1_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_SDIO_D2, GPIO_WLAN_SDIO_D2_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_SDIO_D3, GPIO_WLAN_SDIO_D3_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, +}; + +static unsigned int wlan_sdio_off_table[][4] = { + {GPIO_WLAN_SDIO_CLK, 1, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_SDIO_CMD, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_SDIO_D0, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_SDIO_D1, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_SDIO_D2, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, + {GPIO_WLAN_SDIO_D3, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, +}; + +static void s3c_config_gpio_alive_table(int array_size, unsigned int (*gpio_table)[4]) +{ + u32 i, gpio; + printk("gpio_table = [%d] \r\n" , array_size); + for (i = 0; i < array_size; i++) { + gpio = gpio_table[i][0]; + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(gpio_table[i][1])); + s3c_gpio_setpull(gpio, gpio_table[i][3]); + if (gpio_table[i][2] != GPIO_LEVEL_NONE) + gpio_set_value(gpio, gpio_table[i][2]); + } +} + +static int brcm_wlan_power(int onoff) +{ + printk("------------------------------------------------"); + printk("------------------------------------------------\n"); + printk("%s Enter: power %s\n", __FUNCTION__, onoff ? "on" : "off"); + pr_info("111%s Enter: power %s\n", __FUNCTION__, onoff ? "on" : "off"); + if (onoff) { + s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_on_gpio_table), wlan_on_gpio_table); + udelay(200); + gpio_set_value(GPIO_WLAN_EN, GPIO_LEVEL_HIGH); + printk(KERN_DEBUG "WLAN: GPIO_WLAN_EN = %d \n", gpio_get_value(GPIO_WLAN_EN)); + } else { + gpio_set_value(GPIO_WLAN_EN, GPIO_LEVEL_LOW); + s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_off_gpio_table), wlan_off_gpio_table); + printk(KERN_DEBUG "WLAN: GPIO_WLAN_EN = %d \n", gpio_get_value(GPIO_WLAN_EN)); + } + + return 0; +} + +static int brcm_wlan_reset(int onoff) +{ + gpio_set_value(GPIO_WLAN_EN, + onoff ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW); + return 0; +} + +static int brcm_wlan_set_carddetect(int onoff) +{ + if (onoff) + s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_sdio_on_table), wlan_sdio_on_table); + else + s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_sdio_off_table), wlan_sdio_off_table); + + udelay(200); + + mmc_force_presence_change(&s3c_device_hsmmc3); + /* msleep(500); wait for carddetect */ + return 0; +} + +/* Customized Locale table : OPTIONAL feature */ +#define WLC_CNTRY_BUF_SZ 4 +typedef struct cntry_locales_custom { + char iso_abbrev[WLC_CNTRY_BUF_SZ]; + char custom_locale[WLC_CNTRY_BUF_SZ]; + int custom_locale_rev; +} cntry_locales_custom_t; + +static cntry_locales_custom_t brcm_wlan_translate_custom_table[] = { + /* Table should be filled out based on custom platform regulatory requirement */ + {"", "XZ", 11}, /* Universal if Country code is unknown or empty */ + {"AE", "AE", 1}, + {"AR", "AR", 1}, + {"AT", "AT", 1}, + {"AU", "AU", 2}, + {"BE", "BE", 1}, + {"BG", "BG", 1}, + {"BN", "BN", 1}, + {"CA", "CA", 2}, + {"CH", "CH", 1}, + {"CY", "CY", 1}, + {"CZ", "CZ", 1}, + {"DE", "DE", 3}, + {"DK", "DK", 1}, + {"EE", "EE", 1}, + {"ES", "ES", 1}, + {"FI", "FI", 1}, + {"FR", "FR", 1}, + {"GB", "GB", 1}, + {"GR", "GR", 1}, + {"HR", "HR", 1}, + {"HU", "HU", 1}, + {"IE", "IE", 1}, + {"IS", "IS", 1}, + {"IT", "IT", 1}, + {"JP", "JP", 3}, + {"KR", "KR", 24}, + {"KW", "KW", 1}, + {"LI", "LI", 1}, + {"LT", "LT", 1}, + {"LU", "LU", 1}, + {"LV", "LV", 1}, + {"MA", "MA", 1}, + {"MT", "MT", 1}, + {"MX", "MX", 1}, + {"NL", "NL", 1}, + {"NO", "NO", 1}, + {"PL", "PL", 1}, + {"PT", "PT", 1}, + {"PY", "PY", 1}, + {"RO", "RO", 1}, + {"RU", "RU", 5}, + {"SE", "SE", 1}, + {"SG", "SG", 4}, + {"SI", "SI", 1}, + {"SK", "SK", 1}, + {"TR", "TR", 7}, + {"TW", "TW", 2}, + {"US", "US", 46} +}; + +static void *brcm_wlan_get_country_code(char *ccode) +{ + int size = ARRAY_SIZE(brcm_wlan_translate_custom_table); + int i; + + if (!ccode) + return NULL; + + for (i = 0; i < size; i++) + if (strcmp(ccode, brcm_wlan_translate_custom_table[i].iso_abbrev) == 0) + return &brcm_wlan_translate_custom_table[i]; + return &brcm_wlan_translate_custom_table[0]; +} + +static struct resource brcm_wlan_resources[] = { + [0] = { + .name = "bcmdhd_wlan_irq", + .start = IRQ_EINT(21), + .end = IRQ_EINT(21), +//chanyun 12.21 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE, + }, +}; + +static struct wifi_platform_data brcm_wlan_control = { + .set_power = brcm_wlan_power, + .set_reset = brcm_wlan_reset, + .set_carddetect = brcm_wlan_set_carddetect, +#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM + .mem_prealloc = brcm_wlan_mem_prealloc, +#endif + .get_country_code = brcm_wlan_get_country_code, +}; + +static struct platform_device brcm_device_wlan = { + .name = "bcmdhd_wlan", + .id = 1, + .num_resources = ARRAY_SIZE(brcm_wlan_resources), + .resource = brcm_wlan_resources, + .dev = { + .platform_data = &brcm_wlan_control, + }, +}; + +int __init brcm_wlan_init(void) +{ + int ret; + printk("%s: start\n", __FUNCTION__); + +#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM + brcm_init_wlan_mem(); +#endif + + ret = platform_device_register(&brcm_device_wlan); + printk("-----------------------------------------------------\n"); + printk("-----------------------------------------------------\n"); + printk("-----------------------------------------------------\n"); + printk("regist ret:%d\n", ret); + return ret; + +// return platform_device_register(&brcm_device_wlan); +} |