we simulate card detection by power/reset on or off the card.
Select this option if you want to have your system wake up
from USB.
+config WIFI_CONTROL_FUNC
+ bool "Enable WiFi control function abstraction"
+ help
+ Enables Power/Reset/Carddetect function abstraction
endif
* SDMMC devices
*author: kfx
*****************************************************************************************/
+
static int rk2818_sdmmc0_io_init(void)
{
rk2818_mux_api_set(GPIOF3_APWM1_MMC0DETN_NAME, IOMUXA_SDMMC1_DETECT_N);
.use_dma = 0,
#endif
};
+
+static int info_wifi_status(struct device *dev);
+static int info_wifi_status_register(void (*callback)(int card_presend, void *dev_id), void *dev_id);
struct rk2818_sdmmc_platform_data default_sdmmc1_data = {
.host_ocr_avail = (MMC_VDD_26_27|MMC_VDD_27_28|MMC_VDD_28_29|
MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32|
#else
.use_dma = 0,
#endif
+ .status = info_wifi_status,
+ .register_status_notify = info_wifi_status_register,
};
+static int info_wifi_cd; /* wifi virtual 'card detect' status */
+static void (*wifi_status_cb)(int card_present, void *dev_id);
+static void *wifi_status_cb_devid;
+
+static int info_wifi_status(struct device *dev)
+{
+ return info_wifi_cd;
+}
+
+static int info_wifi_status_register(void (*callback)(int card_present, void *dev_id), void *dev_id)
+{
+ if(wifi_status_cb)
+ return -EAGAIN;
+ wifi_status_cb = callback;
+ wifi_status_cb_devid = dev_id;
+ return 0;
+}
+
+static int info_wifi_power_state;
+static int info_wifi_power(int on)
+{
+ pr_info("%s: %d\n", __func__, on);
+ gpio_set_value(TCA6424_P25, on);
+ mdelay(100);
+ info_wifi_power_state = on;
+ return 0;
+}
+
+static int info_wifi_reset_state;
+static int info_wifi_reset(int on)
+{
+ pr_info("%s: %d\n", __func__, on);
+ gpio_set_value(TCA6424_P27, on);
+ mdelay(100);
+ info_wifi_reset_state = on;
+ return 0;
+}
+
+static int info_wifi_set_carddetect(int val)
+{
+ pr_info("%s:%d\n", __func__, val);
+ info_wifi_cd = val;
+ if (wifi_status_cb){
+ wifi_status_cb(val, wifi_status_cb_devid);
+ }else {
+ pr_warning("%s, nobody to notify\n", __func__);
+ }
+ return 0;
+}
+
+static struct wifi_platform_data info_wifi_control = {
+ .set_power = info_wifi_power,
+ .set_reset = info_wifi_reset,
+ .set_carddetect = info_wifi_set_carddetect,
+};
+static struct platform_device info_wifi_device = {
+ .name = "bcm4329_wlan",
+ .id = 1,
+ .dev = {
+ .platform_data = &info_wifi_control,
+ },
+};
+
+
/*****************************************************************************************
* extern gpio devices
*author: xxx
{
.gpio_num = TCA6424_P25, //wifi reg on
.pin_type = GPIO_OUT,
- .pin_value = GPIO_HIGH,
+ .pin_value = GPIO_LOW,
},
{
.gpio_num = TCA6424_P27, //wifi reset
.pin_type = GPIO_OUT,
- .pin_value = GPIO_HIGH,
+ .pin_value = GPIO_LOW,
},
-{
- .gpio_num = TCA6424_P25, //wifi reg on
- .pin_type = GPIO_OUT,
- .pin_value = GPIO_HIGH,
- },
- {
- .gpio_num = TCA6424_P27, //wifi reset
- .pin_type = GPIO_OUT,
- .pin_value = GPIO_HIGH,
- },
};
void tca6424_reset_itr(void)
#endif
#ifdef CONFIG_SDMMC1_RK2818
&rk2818_device_sdmmc1,
+ &info_wifi_device,
#endif
&rk2818_device_spim,
&rk2818_device_i2s,
char dma_name[8];
int (*io_init)(void);
int (*io_deinit)(void);
+ int (*status)(struct device *);
+ int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
+};
+
+struct wifi_platform_data {
+ int (*set_power)(int val);
+ int (*set_reset)(int val);
+ int (*set_carddetect)(int val);
+ void *(*mem_prealloc)(int section, unsigned long size);
+};
+
+struct wifi_power_gpio_control_data {
+ unsigned int use_gpio; /* If uses GPIO to control wifi power supply. 0 - no, 1 - yes. */
+ unsigned int gpio_iomux; /* If the GPIO is iomux. 0 - no, 1 - yes. */
+ char *iomux_name; /* IOMUX name */
+ unsigned int iomux_value; /* IOMUX value - which function is choosen. */
+ unsigned int gpio_id; /* GPIO number */
+ unsigned int sensi_level; /* GPIO sensitive level. */
};
struct rk2818_i2c_spi_data {
struct mmc_command stop_mannual;
struct timer_list detect_timer;
+ unsigned int oldstatus; /* save old status */
};
#define MMC_DEBUG 0
return result;
}
+static void rk2818_sdmmc_check_status(unsigned long data)
+{
+ struct rk2818_sdmmc_host *host = (struct rk2818_sdmmc_host *)data;
+ struct rk2818_sdmmc_platform_data *pdata = host->pdev->dev.platform_data;
+ unsigned int status;
+
+ if (!pdata->status)
+ {
+ mmc_detect_change(host->mmc, 0);
+ return;
+ }
+
+ status = pdata->status(mmc_dev(host->mmc));
+
+ if (status ^ host->oldstatus)
+ {
+ pr_info("%s: slot status change detected(%d-%d)\n",mmc_hostname(host->mmc), host->oldstatus, status);
+ if (status)
+ mmc_detect_change(host->mmc, 100);
+ else
+ mmc_detect_change(host->mmc, 0);
+ }
+
+ host->oldstatus = status;
+
+}
+
+static void rk2818_sdmmc_status_notify_cb(int card_present, void *dev_id)
+{
+ struct rk2818_sdmmc_host *host = dev_id;
+ printk(KERN_INFO "%s, card_present %d\n", mmc_hostname(host->mmc), card_present);
+ rk2818_sdmmc_check_status((unsigned long)host);
+}
+
/*-------------------end of add communication interface with applications ---------------------------------*/
static int rk2818_sdmmc_probe(struct platform_device *pdev)
goto err_free_map;
}
+ /* setup wifi card detect change */
+ if (pdata->register_status_notify)
+ {
+ pdata->register_status_notify(rk2818_sdmmc_status_notify_cb, host);
+ }
spin_lock_init(&host->lock);
INIT_LIST_HEAD(&host->queue);
wl-objs := wl_iw.o
-bcm4329-objs := $(bcmsdio-objs) $(dhd-objs) $(shared-objs) $(wl-objs) wifi_power.o
+bcm4329-objs := $(bcmsdio-objs) $(dhd-objs) $(shared-objs) $(wl-objs)
obj-$(CONFIG_BCM4329) += bcm4329.o
#include <dhd_dbg.h>
-#include "wifi_power.h"
-
extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
-extern struct mmc_host *wifi_mmc_host;
-extern void mmc_detect_change(struct mmc_host *host, unsigned long delay);
-extern int wifi_turn_on_card(void);
-extern int wifi_turn_off_card(void);
-extern int wifi_power_up_wifi(void);
-extern int wifi_power_down_wifi(void);
-
int sdio_function_init(void);
void sdio_function_cleanup(void);
*/
int sdio_function_init(void)
{
- int error = 0, timeout;
+ int error = 0;
sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__));
gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL);
bzero(&sdmmc_dev, sizeof(sdmmc_dev));
error = sdio_register_driver(&bcmsdh_sdmmc_driver);
-#ifdef WIFI_GPIO_POWER_CONTROL
-
- if (wifi_mmc_host->bus_ops != NULL)
- {
- printk(KERN_INFO "SDIO card maybe be attached already\n");
- return 0;
- }
-
- wifi_turn_on_card();
- wifi_power_up_wifi();
-
- mmc_detect_change(wifi_mmc_host, 5);
-
- timeout = 100;
-
- do{
- if (gInstance->func[0] != NULL)
- break;
- msleep(20);
- }while(--timeout);
-
- if (timeout <= 0){
- printk(KERN_INFO "no wifi card is found\n");
- error = 0;
- }
-#endif
-
return error;
}
* $Id: dhd_linux.c,v 1.65.4.9.2.12.2.89 2010/07/21 18:07:11 Exp $
*/
+
#ifdef CONFIG_WIFI_CONTROL_FUNC
#include <linux/platform_device.h>
#endif
#include <dhd_proto.h>
#include <dhd_dbg.h>
-
-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
-#include <linux/wifi_tiwlan.h>
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+#include <mach/board.h>
struct semaphore wifi_control_sem;
struct dhd_bus *g_bus;
static struct wifi_platform_data *wifi_control_data = NULL;
-static struct resource *wifi_irqres = NULL;
-
+//static struct resource *wifi_irqres = NULL;
+#if 0
int wifi_get_irq_number(unsigned long *irq_flags_ptr)
{
if (wifi_irqres) {
return -1;
#endif
}
+#endif
int wifi_set_carddetect(int on)
{
(struct wifi_platform_data *)(pdev->dev.platform_data);
printk("## %s\n", __FUNCTION__);
- wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcm4329_wlan_irq");
+// wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcm4329_wlan_irq");
wifi_control_data = wifi_ctrl;
wifi_set_power(1, 0); /* Power On */
+ wifi_set_reset(1, 0);
wifi_set_carddetect(1); /* CardDetect (0->1) */
up(&wifi_control_sem);
printk("## %s\n", __FUNCTION__);
wifi_control_data = wifi_ctrl;
-
+
+ wifi_set_power(0, 0);
+ wifi_set_reset(0, 0);
wifi_set_carddetect(0); /* CardDetect (1->0) */
- wifi_set_power(0, 0); /* Power Off */
up(&wifi_control_sem);
return 0;
DHD_TRACE(("## Unregister platform_driver_register\n"));
platform_driver_unregister(&wifi_device);
}
-#endif /* defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */
+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
*/
memcpy(netdev_priv(net), &dhd, sizeof(dhd));
-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
g_bus = bus;
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) && 1
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
dhd_bus_unregister();
-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
wifi_del_dev();
#endif
/* Call customer gpio to turn off power with WL_REG_ON signal */
/* Call customer gpio to turn on power with WL_REG_ON signal */
dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
sema_init(&wifi_control_sem, 0);
error = wifi_add_dev();
+++ /dev/null
-/*
- * wifi_power.c
- *
- * Power control for WIFI module.
- *
- * There are Power supply and Power Up/Down controls for WIFI typically.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#if defined(CONFIG_MACH_RAHO)
-#include <linux/i2c.h>
-#include <mach/spi_fpga.h>
-#elif defined(CONFIG_MACH_RK2818INFO)
-/* include gpio definition header file */
-#endif
-#include "wifi_power.h"
-
-#if (WIFI_GPIO_POWER_CONTROL == 1)
-#if defined(CONFIG_MACH_RAHO)
-struct wifi_power power_gpio =
-{
- POWER_USE_GPIO, 0, 0, 0, SPI_GPIO_P1_06, SPI_GPIO_HIGH
-};
-
-struct wifi_power power_save_gpio =
-{
- POWER_USE_GPIO, 0, 0, 0, SPI_GPIO_P1_03, SPI_GPIO_HIGH
-};
-#elif defined(CONFIG_MACH_RK2818INFO)
-struct wifi_power power_gpio = {
- 0,0,0,0,0,0
-};
-
-struct wifi_power power_save_gpio = {
- 0,0,0,0,0,0
-};
-#endif
-
-int wifi_gpio_operate(struct wifi_power *gpio, int flag)
-{
- int sensitive;
-
- if (gpio->use_gpio == POWER_NOT_USE_GPIO)
- return 0;
- if (gpio->gpio_iomux == POWER_GPIO_IOMUX)
- {
- rk2818_mux_api_set(gpio->iomux_name, gpio->iomux_value);
- }
-
-#if defined(CONFIG_MACH_RAHO)
- spi_gpio_set_pindirection(gpio->gpio_id, SPI_GPIO_OUT);
-#elif defined(CONFIG_MACH_RK2818INFO)
- /* set pin direction */
-#endif
-
- if (flag == GPIO_SWITCH_ON)
- sensitive = gpio->sensi_level;
- else
- sensitive = 1 - gpio->sensi_level;
-
-#if defined(CONFIG_MACH_RAHO)
- spi_gpio_set_pinlevel(gpio->gpio_id, sensitive);
-#elif defined(CONFIG_MACH_RK2818INFO)
- /* set pin level */
-#endif
-
- return 0;
-}
-
-
-int wifi_turn_on_card(void)
-{
-
- if (wifi_gpio_operate(&power_gpio, GPIO_SWITCH_ON) != 0)
- {
- printk("Couldn't set GPIO [ON] successfully for power supply.\n");
- return -1;
- }
-
- return 0;
-}
-
-int wifi_turn_off_card(void)
-{
-
- if (wifi_gpio_operate(&power_gpio, GPIO_SWITCH_OFF) != 0)
- {
- printk("Couldn't set GPIO [OFF] successfully for power supply.\n");
- return -1;
- }
-
- return 0;
-}
-
-int wifi_power_up_wifi(void)
-{
-
- if (wifi_gpio_operate(&power_save_gpio, GPIO_SWITCH_ON) != 0)
- {
- printk("Couldn't set GPIO [ON] successfully for power up.\n");
- return -1;
- }
- mdelay(5);
-
- if (wifi_gpio_operate(&power_save_gpio, GPIO_SWITCH_OFF) != 0)
- {
- printk("Couldn't set GPIO [ON] successfully for power up.\n");
- return -1;
- }
- msleep(150);
-
- if (wifi_gpio_operate(&power_save_gpio, GPIO_SWITCH_ON) != 0)
- {
- printk("Couldn't set GPIO [ON] successfully for power up.\n");
- return -1;
- }
- msleep(50);
-
- return 0;
-}
-
-int wifi_power_down_wifi(void)
-{
- if (wifi_gpio_operate(&power_save_gpio, GPIO_SWITCH_OFF) != 0)
- {
- printk("Couldn't set GPIO [OFF] successfully for power down.\n");
- return -1;
- }
-
- return 0;
-}
-
-#endif /* WIFI_GPIO_POWER_CONTROL */
-
+++ /dev/null
-/*
- * wifi_power.h
- *
- * WIFI power control.
- *
- * Yongle Lai
- */
-
-#ifndef WIFI_POWER_H
-#define WIFI_POWER_H
-
-#define WIFI_GPIO_POWER_CONTROL 1
-
-#if (WIFI_GPIO_POWER_CONTROL == 1)
-
-#include <mach/gpio.h>
-#include <mach/iomux.h>
-
-#define POWER_NOT_USE_GPIO 0
-#define POWER_USE_GPIO 1
-
-#define POWER_GPIO_NOT_IOMUX 0
-#define POWER_GPIO_IOMUX 1
-
-#define GPIO_SWITCH_OFF 0
-#define GPIO_SWITCH_ON 1
-
-struct wifi_power
-{
- u8 use_gpio; /* If uses GPIO to control wifi power supply. 0 - no, 1 - yes. */
- u8 gpio_iomux; /* If the GPIO is iomux. 0 - no, 1 - yes. */
- char *iomux_name; /* IOMUX name */
- u8 iomux_value; /* IOMUX value - which function is choosen. */
- u8 gpio_id; /* GPIO number */
- u8 sensi_level; /* GPIO sensitive level. */
-};
-
-/*
- * Power supply via control GPIO.
- */
-#define POWER_VIA_GPIO 1 /* */
-#define POWER_GPIO_MUTEX 1 /* 1 - GPIO is a io mutexed IO */
-#define POWER_GPIO_MUTEX_NAME GPIOH6_IQ_SEL_NAME
-#define POWER_GPIO_MUTEXT_VAL IOMUXB_GPIO1_D6
-#define POWER_GPIO_ID GPIOPortH_Pin6
-#define POWER_LEVEL_SENSITIVE GPIO_HIGH
-
-int wifi_turn_on_card(void);
-int wifi_turn_off_card(void);
-int wifi_power_up_wifi(void);
-int wifi_power_down_wifi(void);
-int wifi_power_reset(void);
-
-#endif /* WIFI_GPIO_POWER_CONTROL */
-
-#endif /* WIFI_POWER_H */