Merge remote-tracking branch 'last/develop-3.0' into develop-3.0

This commit is contained in:
黄涛
2011-11-25 17:47:39 +08:00
153 changed files with 30630 additions and 18887 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1066,6 +1066,7 @@ CONFIG_GPIOLIB=y
# CONFIG_GPIO_PCA953X is not set
# CONFIG_GPIO_PCF857X is not set
CONFIG_GPIO_WM831X=y
CONFIG_GPIO_WM8994=y
#
# PCI GPIO expanders:
@@ -1128,13 +1129,13 @@ CONFIG_MFD_CORE=y
# CONFIG_MFD_TC6387XB is not set
# CONFIG_MFD_TC6393XB is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8994 is not set
# CONFIG_MFD_WM8400 is not set
CONFIG_MFD_WM831X=y
# CONFIG_MFD_WM831X_I2C is not set
CONFIG_MFD_WM831X_SPI=y
# CONFIG_MFD_WM831X_SPI_A22 is not set
# CONFIG_MFD_WM8350_I2C is not set
CONFIG_MFD_WM8994=y
# CONFIG_MFD_PCF50633 is not set
# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
@@ -1147,6 +1148,7 @@ CONFIG_REGULATOR=y
# CONFIG_REGULATOR_BQ24022 is not set
# CONFIG_REGULATOR_MAX1586 is not set
CONFIG_REGULATOR_WM831X=y
CONFIG_REGULATOR_WM8994=y
# CONFIG_REGULATOR_LP3971 is not set
# CONFIG_REGULATOR_TPS65023 is not set
# CONFIG_REGULATOR_TPS6507X is not set
@@ -1660,7 +1662,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_SDMMC_RK29_OLD=y
# CONFIG_SDMMC_RK29_OLD=y
CONFIG_SDMMC_RK29=y
#

File diff suppressed because it is too large Load Diff

View File

@@ -23,6 +23,12 @@ config MACH_RK29WINACCORD
help
Support for the ROCKCHIP Board For Rk29 Winaccord.
config MACH_RK29_K97
depends on ARCH_RK29
bool "ROCKCHIP Board Rk29 For K97"
help
Support for the ROCKCHIP Board For Rk29 K97.
config MACH_RK29FIH
depends on ARCH_RK29
bool "ROCKCHIP Board Rk29 For FIH"
@@ -47,6 +53,12 @@ config MACH_RK29_A22
help
Support for the ROCKCHIP Board For A22.
config MACH_RK29_TD8801_V2
depends on ARCH_RK29
bool "ROCKCHIP Board Rk29 For TD8801_v2"
help
Support for the ROCKCHIP Board For TD8801_v2.
config MACH_RK29_PHONEPADSDK
depends on ARCH_RK29
bool "ROCKCHIP Board Rk29 For Phone Pad Sdk"

View File

@@ -21,6 +21,8 @@ obj-$(CONFIG_MACH_RK29_MALATA) += board-malata.o board-rk29malata-key.o board-rk
obj-$(CONFIG_MACH_RK29_PHONESDK) += board-rk29-phonesdk.o board-rk29-phonesdk-key.o board-rk29-phonesdk-rfkill.o
obj-$(CONFIG_MACH_RK29FIH) += board-rk29-fih.o board-rk29-fih-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o
obj-$(CONFIG_MACH_RK29_A22) += board-rk29-a22.o board-rk29-a22-key.o board-rk29-a22-rfkill.o
obj-$(CONFIG_MACH_RK29_TD8801_V2) += board-rk29-td8801_v2.o board-rk29-td8801_v2-key.o board-rk29-td8801_v2-rfkill.o
obj-$(CONFIG_MACH_RK29_PHONEPADSDK) += board-rk29phonepadsdk.o board-rk29phonepadsdk-key.o board-rk29phonepadsdk-rfkill.o board-rk29phonepadsdk-power.o
obj-$(CONFIG_MACH_RK29_newton) += board-rk29-newton.o board-rk29-newton-key.o board-newton-rfkill.o board-rk29sdk-power.o
obj-$(CONFIG_MACH_RK29_K97) += board-rk29-k97.o board-rk29k97-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o

View File

@@ -71,6 +71,7 @@
#define CONFIG_SENSOR_0 RK29_CAM_SENSOR_OV5642 /* back camera sensor */
#define CONFIG_SENSOR_IIC_ADDR_0 0x78
#define CONFIG_SENSOR_IIC_ADAPTER_ID_0 1
#define CONFIG_SENSOR_ORIENTATION_0 0
#define CONFIG_SENSOR_POWER_PIN_0 INVALID_GPIO
#define CONFIG_SENSOR_RESET_PIN_0 INVALID_GPIO
#define CONFIG_SENSOR_POWERDN_PIN_0 RK29_PIN6_PB7
@@ -83,6 +84,7 @@
#define CONFIG_SENSOR_1 RK29_CAM_SENSOR_OV2659 /* front camera sensor */
#define CONFIG_SENSOR_IIC_ADDR_1 0x60
#define CONFIG_SENSOR_IIC_ADAPTER_ID_1 1
#define CONFIG_SENSOR_ORIENTATION_1 0
#define CONFIG_SENSOR_POWER_PIN_1 INVALID_GPIO
#define CONFIG_SENSOR_RESET_PIN_1 INVALID_GPIO
#define CONFIG_SENSOR_POWERDN_PIN_1 RK29_PIN5_PD7
@@ -1411,14 +1413,14 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
.flags = 0,
},
#endif
#if defined (CONFIG_SND_SOC_alc5621)
#if defined (CONFIG_SND_SOC_RT5621)
{
.type = "ALC5621",
.type = "rt5621",
.addr = 0x1a,
.flags = 0,
},
#endif
#if defined (CONFIG_SND_SOC_alc5631)
#if defined (CONFIG_SND_SOC_RT5631)
{
.type = "rt5631",
.addr = 0x1a,
@@ -1432,6 +1434,13 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
.flags = 0,
},
#endif
#if defined (CONFIG_SND_SOC_WM8988)
{
.type = "wm8988",
.addr = 0x1A,
.flags = 0,
},
#endif
#if defined (CONFIG_SND_SOC_WM8900)
{
.type = "wm8900",

File diff suppressed because it is too large Load Diff

View File

@@ -51,8 +51,6 @@
#include <linux/mfd/wm831x/pdata.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/gpio.h>
#include <linux/mfd/wm8994/pdata.h>
#include <linux/mfd/wm8994/registers.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
@@ -79,7 +77,7 @@
#include "../../../drivers/input/touchscreen/xpt2046_cbn_ts.h"
#endif
#include "../../../drivers/misc/gps/rk29_gps.h"
#include "../../../drivers/serial/sc8800.h"
#include "../../../drivers/tty/serial/sc8800.h"
#ifdef CONFIG_VIDEO_RK29
/*---------------- Camera Sensor Macro Define Begin ------------------------*/
/*---------------- Camera Sensor Configuration Macro Begin ------------------------*/
@@ -160,6 +158,8 @@
#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024)
#define WLAN_SKB_BUF_NUM 16
#define UNLOCK_SECURITY_KEY ~(0x1<<5)
#define LOCK_SECURITY_KEY 0x00
static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
@@ -712,9 +712,14 @@ int wm831x_pre_init(struct wm831x *parm)
wm831x_reg_write(parm, WM831X_POWER_STATE, (ret&0xfff8) | 0x04);
//BATT_FET_ENA = 1
wm831x_set_bits(parm, WM831X_RESET_CONTROL,0x1000,0x1000);
ret = wm831x_reg_read(parm, WM831X_RESET_CONTROL) & 0xffff;
printk("%s:WM831X_RESET_CONTROL=0x%x\n",__FUNCTION__,ret);
wm831x_reg_write(parm,WM831X_SECURITY_KEY,0x9716); // unlock security key
wm831x_set_bits(parm, WM831X_RESET_CONTROL,0x1000,0x1000);
ret = wm831x_reg_read(parm, WM831X_RESET_CONTROL) & 0xffff&UNLOCK_SECURITY_KEY;// enternal reset active in sleep
printk("%s:WM831X_RESET_CONTROL=0x%x\n",__FUNCTION__,ret);
wm831x_reg_write(parm, WM831X_RESET_CONTROL, ret);
wm831x_reg_write(parm,WM831X_SECURITY_KEY,LOCK_SECURITY_KEY); // lock securit
#if 0
wm831x_set_bits(parm, WM831X_LDO_ENABLE, (1 << 3), 0);
@@ -1689,35 +1694,6 @@ struct platform_device rk29_device_gps = {
};
#endif
/*****************************************************************************************
* wm8994 codec
* author: qjb@rock-chips.com
*****************************************************************************************/
struct wm8994_pdata wm8994_platdata = {
.BB_input_diff = 0,
.BB_class = NO_PCM_BB,
.no_earpiece = 0,
.sp_hp_same_channel = 0,
.PA_control_pin = 0,
.Power_EN_Pin = RK29_PIN5_PA1,
.speaker_incall_vol = 0,
.speaker_incall_mic_vol = -9,
.speaker_normal_vol = 6,
.earpiece_incall_vol = 0,
.headset_incall_vol = 6,
.headset_incall_mic_vol = -6,
.headset_normal_vol = -6,
.BT_incall_vol = 0,
.BT_incall_mic_vol = 0,
.recorder_vol = 30,
};
#ifdef CONFIG_RK_HEADSET_DET
#define HEADSET_GPIO RK29_PIN4_PD2
struct rk_headset_pdata rk_headset_info = {
@@ -1928,9 +1904,6 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
.type = "wm8994",
.addr = 0x1a,
.flags = 0,
// #if defined(CONFIG_MFD_WM8994)
.platform_data = &wm8994_platdata,
// #endif
},
#endif
#if defined (CONFIG_BATTERY_STC3100)
@@ -2312,10 +2285,239 @@ struct platform_device rk2818_device_mtk23d = {
};
#endif
/*****************************************************************************************
* SDMMC devices
*****************************************************************************************/
#if !defined(CONFIG_SDMMC_RK29_OLD)
static void rk29_sdmmc_gpio_open(int device_id, int on)
{
switch(device_id)
{
case 0://mmc0
{
#ifdef CONFIG_SDMMC0_RK29
if(on)
{
gpio_direction_output(RK29_PIN1_PD0,GPIO_HIGH);//set mmc0-clk to high
gpio_direction_output(RK29_PIN1_PD1,GPIO_HIGH);//set mmc0-cmd to high.
gpio_direction_output(RK29_PIN1_PD2,GPIO_HIGH);//set mmc0-data0 to high.
gpio_direction_output(RK29_PIN1_PD3,GPIO_HIGH);//set mmc0-data1 to high.
gpio_direction_output(RK29_PIN1_PD4,GPIO_HIGH);//set mmc0-data2 to high.
gpio_direction_output(RK29_PIN1_PD5,GPIO_HIGH);//set mmc0-data3 to high.
mdelay(30);
}
else
{
rk29_mux_api_set(GPIO1D0_SDMMC0CLKOUT_NAME, GPIO1H_GPIO1_D0);
gpio_request(RK29_PIN1_PD0, "mmc0-clk");
gpio_direction_output(RK29_PIN1_PD0,GPIO_LOW);//set mmc0-clk to low.
rk29_mux_api_set(GPIO1D1_SDMMC0CMD_NAME, GPIO1H_GPIO1_D1);
gpio_request(RK29_PIN1_PD1, "mmc0-cmd");
gpio_direction_output(RK29_PIN1_PD1,GPIO_LOW);//set mmc0-cmd to low.
rk29_mux_api_set(GPIO1D2_SDMMC0DATA0_NAME, GPIO1H_GPIO1D2);
gpio_request(RK29_PIN1_PD2, "mmc0-data0");
gpio_direction_output(RK29_PIN1_PD2,GPIO_LOW);//set mmc0-data0 to low.
rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_GPIO1D3);
gpio_request(RK29_PIN1_PD3, "mmc0-data1");
gpio_direction_output(RK29_PIN1_PD3,GPIO_LOW);//set mmc0-data1 to low.
rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_GPIO1D4);
gpio_request(RK29_PIN1_PD4, "mmc0-data2");
gpio_direction_output(RK29_PIN1_PD4,GPIO_LOW);//set mmc0-data2 to low.
rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_GPIO1D5);
gpio_request(RK29_PIN1_PD5, "mmc0-data3");
gpio_direction_output(RK29_PIN1_PD5,GPIO_LOW);//set mmc0-data3 to low.
mdelay(30);
}
#endif
}
break;
case 1://mmc1
{
#ifdef CONFIG_SDMMC1_RK29
if(on)
{
gpio_direction_output(RK29_PIN1_PC7,GPIO_HIGH);//set mmc1-clk to high
gpio_direction_output(RK29_PIN1_PC2,GPIO_HIGH);//set mmc1-cmd to high.
gpio_direction_output(RK29_PIN1_PC3,GPIO_HIGH);//set mmc1-data0 to high.
gpio_direction_output(RK29_PIN1_PC4,GPIO_HIGH);//set mmc1-data1 to high.
gpio_direction_output(RK29_PIN1_PC5,GPIO_HIGH);//set mmc1-data2 to high.
gpio_direction_output(RK29_PIN1_PC6,GPIO_HIGH);//set mmc1-data3 to high.
mdelay(100);
}
else
{
rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_GPIO1C7);
gpio_request(RK29_PIN1_PC7, "mmc1-clk");
gpio_direction_output(RK29_PIN1_PC7,GPIO_LOW);//set mmc1-clk to low.
rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_GPIO1C2);
gpio_request(RK29_PIN1_PC2, "mmc1-cmd");
gpio_direction_output(RK29_PIN1_PC2,GPIO_LOW);//set mmc1-cmd to low.
rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_GPIO1C3);
gpio_request(RK29_PIN1_PC3, "mmc1-data0");
gpio_direction_output(RK29_PIN1_PC3,GPIO_LOW);//set mmc1-data0 to low.
mdelay(100);
}
#endif
}
break;
case 2: //mmc2
break;
default:
break;
}
}
static void rk29_sdmmc_set_iomux_mmc0(unsigned int bus_width)
{
switch (bus_width)
{
case 1://SDMMC_CTYPE_4BIT:
{
rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_SDMMC0_DATA1);
rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_SDMMC0_DATA2);
rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_SDMMC0_DATA3);
}
break;
case 0x10000://SDMMC_CTYPE_8BIT:
break;
case 0xFFFF: //gpio_reset
{
rk29_mux_api_set(GPIO5D5_SDMMC0PWREN_NAME, GPIO5H_GPIO5D5);
gpio_request(RK29_PIN5_PD5,"sdmmc-power");
gpio_direction_output(RK29_PIN5_PD5,GPIO_HIGH); //power-off
rk29_sdmmc_gpio_open(0, 0);
gpio_direction_output(RK29_PIN5_PD5,GPIO_LOW); //power-on
rk29_sdmmc_gpio_open(0, 1);
}
break;
default: //case 0://SDMMC_CTYPE_1BIT:
{
rk29_mux_api_set(GPIO1D1_SDMMC0CMD_NAME, GPIO1H_SDMMC0_CMD);
rk29_mux_api_set(GPIO1D0_SDMMC0CLKOUT_NAME, GPIO1H_SDMMC0_CLKOUT);
rk29_mux_api_set(GPIO1D2_SDMMC0DATA0_NAME, GPIO1H_SDMMC0_DATA0);
rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_GPIO1D3);
gpio_request(RK29_PIN1_PD3, "mmc0-data1");
gpio_direction_output(RK29_PIN1_PD3,GPIO_HIGH);
rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_GPIO1D4);
gpio_request(RK29_PIN1_PD4, "mmc0-data2");
gpio_direction_output(RK29_PIN1_PD4,GPIO_HIGH);
rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_GPIO1D5);
gpio_request(RK29_PIN1_PD5, "mmc0-data3");
gpio_direction_output(RK29_PIN1_PD5,GPIO_HIGH);
}
break;
}
}
static void rk29_sdmmc_set_iomux_mmc1(unsigned int bus_width)
{
#if 0
switch (bus_width)
{
case 1://SDMMC_CTYPE_4BIT:
{
rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_SDMMC1_CMD);
rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_SDMMC1_CLKOUT);
rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_SDMMC1_DATA0);
rk29_mux_api_set(GPIO1C4_SDMMC1DATA1_NAME, GPIO1H_SDMMC1_DATA1);
rk29_mux_api_set(GPIO1C5_SDMMC1DATA2_NAME, GPIO1H_SDMMC1_DATA2);
rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_SDMMC1_DATA3);
}
break;
case 0x10000://SDMMC_CTYPE_8BIT:
break;
case 0xFFFF:
{
rk29_sdmmc_gpio_open(1, 0);
rk29_sdmmc_gpio_open(1, 1);
}
break;
default: //case 0://SDMMC_CTYPE_1BIT:
{
rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_SDMMC1_CMD);
rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_SDMMC1_CLKOUT);
rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_SDMMC1_DATA0);
rk29_mux_api_set(GPIO1C4_SDMMC1DATA1_NAME, GPIO1H_GPIO1C4);
gpio_request(RK29_PIN1_PC4, "mmc1-data1");
gpio_direction_output(RK29_PIN1_PC4,GPIO_HIGH);
rk29_mux_api_set(GPIO1C5_SDMMC1DATA2_NAME, GPIO1H_GPIO1C5);
gpio_request(RK29_PIN1_PC5, "mmc1-data2");
gpio_direction_output(RK29_PIN1_PC5,GPIO_HIGH);
rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_GPIO1C6);
gpio_request(RK29_PIN1_PC6, "mmc1-data3");
gpio_direction_output(RK29_PIN1_PC6,GPIO_HIGH);
}
break;
}
#else
rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_SDMMC1_CMD);
rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_SDMMC1_CLKOUT);
rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_SDMMC1_DATA0);
rk29_mux_api_set(GPIO1C4_SDMMC1DATA1_NAME, GPIO1H_SDMMC1_DATA1);
rk29_mux_api_set(GPIO1C5_SDMMC1DATA2_NAME, GPIO1H_SDMMC1_DATA2);
rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_SDMMC1_DATA3);
#endif
}
static void rk29_sdmmc_set_iomux_mmc2(unsigned int bus_width)
{
;//
}
static void rk29_sdmmc_set_iomux(int device_id, unsigned int bus_width)
{
switch(device_id)
{
case 0:
#ifdef CONFIG_SDMMC0_RK29
rk29_sdmmc_set_iomux_mmc0(bus_width);
#endif
break;
case 1:
#ifdef CONFIG_SDMMC1_RK29
rk29_sdmmc_set_iomux_mmc1(bus_width);
#endif
break;
case 2:
rk29_sdmmc_set_iomux_mmc2(bus_width);
break;
default:
break;
}
}
#endif
#ifdef CONFIG_SDMMC0_RK29
static int rk29_sdmmc0_cfg_gpio(void)
{
@@ -2350,6 +2552,9 @@ struct rk29_sdmmc_platform_data default_sdmmc0_data = {
.use_dma = 1,
#else
.use_dma = 0,
#endif
#if !defined(CONFIG_SDMMC_RK29_OLD)
.set_iomux = rk29_sdmmc_set_iomux,
#endif
.detect_irq = RK29_PIN2_PA2, // INVALID_GPIO
.enable_sd_wakeup = 0,
@@ -2384,6 +2589,9 @@ struct rk29_sdmmc_platform_data default_sdmmc1_data = {
MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
.io_init = rk29_sdmmc1_cfg_gpio,
.dma_name = "sdio",
#if !defined(CONFIG_SDMMC_RK29_OLD)
.set_iomux = rk29_sdmmc_set_iomux,
#endif
#ifdef CONFIG_SDMMC1_USE_DMA
.use_dma = 1,
#else
@@ -3199,8 +3407,12 @@ static int rk29xx_virtual_keys_init(void)
static void __init rk29_gic_init_irq(void)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
gic_init(0, 32, (void __iomem *)RK29_GICPERI_BASE, (void __iomem *)RK29_GICCPU_BASE);
#else
gic_dist_init(0, (void __iomem *)RK29_GICPERI_BASE, 32);
gic_cpu_init(0, (void __iomem *)RK29_GICCPU_BASE);
#endif
}
static void __init machine_rk29_init_irq(void)
@@ -3312,8 +3524,11 @@ static void __init machine_rk29_mapio(void)
MACHINE_START(RK29, "RK29board")
/* UART for LL DEBUG */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37))
/* UART for LL DEBUG */
.phys_io = RK29_UART1_PHYS & 0xfff00000,
.io_pg_offst = ((RK29_UART1_BASE) >> 18) & 0xfffc,
#endif
.boot_params = RK29_SDRAM_PHYS + 0x88000,
.fixup = machine_rk29_fixup,
.map_io = machine_rk29_mapio,

View File

@@ -0,0 +1,105 @@
#include <mach/key.h>
#include <mach/gpio.h>
#define EV_ENCALL KEY_F4
#define EV_MENU KEY_F1
#define PRESS_LEV_LOW 1
#define PRESS_LEV_HIGH 0
static struct rk29_keys_button key_button[] = {
{
.desc = "menu",
.code = EV_MENU,
.gpio = RK29_PIN6_PA0,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "vol+",
.code = KEY_VOLUMEUP,
.gpio = RK29_PIN6_PA1,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "vol-",
.code = KEY_VOLUMEDOWN,
.gpio = RK29_PIN6_PA2,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "home",
.code = KEY_HOME,
.gpio = RK29_PIN6_PA3,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "search",
.code = KEY_SEARCH,
.gpio = RK29_PIN6_PA4,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "esc",
.code = KEY_BACK,
.gpio = RK29_PIN6_PA5,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "sensor",
.code = KEY_CAMERA,
.gpio = RK29_PIN6_PA6,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "play",
.code = KEY_POWER,
.gpio = RK29_PIN6_PA7,
.active_low = PRESS_LEV_LOW,
.wakeup = 1,
},
#if 0
{
.desc = "vol+",
.code = KEY_VOLUMEDOWN,
.adc_value = 95,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "vol-",
.code = KEY_VOLUMEUP,
.adc_value = 249,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "menu",
.code = EV_MENU,
.adc_value = 406,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "home",
.code = KEY_HOME,
.code_long_press = KEY_F4,
.adc_value = 561,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "esc",
.code = KEY_ESC,
.adc_value = 726,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "adkey6",
.code = KEY_BACK,
.code_long_press = EV_ENCALL,
.adc_value = 899,
.active_low = PRESS_LEV_LOW,
},
#endif
};
struct rk29_keys_platform_data rk29_keys_pdata = {
.buttons = key_button,
.nbuttons = ARRAY_SIZE(key_button),
.chn = -1, //chn: 0-7, if do not use ADC,set 'chn' -1
};

View File

@@ -0,0 +1,313 @@
/*
* Copyright (C) 2010 ROCKCHIP, Inc.
* Author: roger_chen <cz@rock-chips.com>
*
* This program is the bluetooth device bcm4329's driver,
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/rfkill.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/wakelock.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <mach/gpio.h>
#include <asm/irq.h>
#include <mach/iomux.h>
#include <linux/wakelock.h>
#include <linux/timer.h>
#include <mach/board.h>
#if 0
#define DBG(x...) printk(KERN_INFO x)
#else
#define DBG(x...)
#endif
#define BT_WAKE_HOST_SUPPORT 1
struct bt_ctrl
{
struct rfkill *bt_rfk;
#if BT_WAKE_HOST_SUPPORT
struct timer_list tl;
bool b_HostWake;
struct wake_lock bt_wakelock;
#endif
};
#define BT_GPIO_POWER RK29_PIN5_PD6
#define IOMUX_BT_GPIO_POWER rk29_mux_api_set(GPIO5D6_SDMMC1PWREN_NAME, GPIO5H_GPIO5D6);
#define BT_GPIO_RESET RK29_PIN6_PC7
#define BT_GPIO_WAKE_UP RK29_PIN6_PD0
#define BT_GPIO_WAKE_UP_HOST RK29_PIN4_PD4
#define IOMUX_BT_GPIO_WAKE_UP_HOST() rk29_mux_api_set(GPIO4D4_CPUTRACECLK_NAME,GPIO4H_GPIO4D4);
//bt cts paired to uart rts
#define UART_RTS RK29_PIN2_PA7
#define IOMUX_UART_RTS_GPIO rk29_mux_api_set(GPIO2A7_UART2RTSN_NAME, GPIO2L_GPIO2A7);
#define IOMUX_UART_RTS rk29_mux_api_set(GPIO2A7_UART2RTSN_NAME, GPIO2L_UART2_RTS_N);
#define BT_WAKE_LOCK_TIMEOUT 10 //s
static const char bt_name[] = "bcm4329";
extern int rk29sdk_bt_power_state;
extern int rk29sdk_wifi_power_state;
struct bt_ctrl gBtCtrl;
#if BT_WAKE_HOST_SUPPORT
void resetBtHostSleepTimer(void)
{
mod_timer(&(gBtCtrl.tl),jiffies + BT_WAKE_LOCK_TIMEOUT*HZ);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>ʱֵ<CAB1><D6B5>
}
void btWakeupHostLock(void)
{
if(gBtCtrl.b_HostWake == false){
DBG("*************************Lock\n");
wake_lock(&(gBtCtrl.bt_wakelock));
gBtCtrl.b_HostWake = true;
}
}
void btWakeupHostUnlock(void)
{
if(gBtCtrl.b_HostWake == true){
DBG("*************************UnLock\n");
wake_unlock(&(gBtCtrl.bt_wakelock)); //<2F><>ϵͳ˯<CDB3><CBAF>
gBtCtrl.b_HostWake = false;
}
}
static void timer_hostSleep(unsigned long arg)
{
DBG("%s---b_HostWake=%d\n",__FUNCTION__,gBtCtrl.b_HostWake);
btWakeupHostUnlock();
}
#ifdef CONFIG_PM
static int bcm4329_rfkill_suspend(struct platform_device *pdev, pm_message_t state)
{
DBG("%s\n",__FUNCTION__);
//To prevent uart to receive bt data when suspended
IOMUX_UART_RTS_GPIO;
gpio_request(UART_RTS, "uart_rts");
gpio_direction_output(UART_RTS, 0);
gpio_set_value(UART_RTS, GPIO_HIGH);
return 0;
}
static int bcm4329_rfkill_resume(struct platform_device *pdev)
{
DBG("%s\n",__FUNCTION__);
btWakeupHostLock();
resetBtHostSleepTimer();
gpio_set_value(UART_RTS, GPIO_LOW);
IOMUX_UART_RTS;
return 0;
}
#else
#define bcm4329_rfkill_suspend NULL
#define bcm4329_rfkill_resume NULL
#endif
static irqreturn_t bcm4329_wake_host_irq(int irq, void *dev)
{
DBG("%s\n",__FUNCTION__);
btWakeupHostLock();
resetBtHostSleepTimer();
return IRQ_HANDLED;
}
#endif
#ifdef CONFIG_BT_HCIBCM4325
int bcm4325_sleep(int bSleep)
{
// printk("*************bt enter sleep***************\n");
if (bSleep)
gpio_set_value(BT_GPIO_WAKE_UP, GPIO_LOW); //low represent bt device may enter sleep
else
gpio_set_value(BT_GPIO_WAKE_UP, GPIO_HIGH); //high represent bt device must be awake
//printk("sleep=%d\n",bSleep);
}
#endif
static int bcm4329_set_block(void *data, bool blocked)
{
DBG("%s---blocked :%d\n", __FUNCTION__, blocked);
IOMUX_BT_GPIO_POWER;
if (false == blocked) {
gpio_set_value(BT_GPIO_POWER, GPIO_HIGH); /* bt power on */
gpio_set_value(BT_GPIO_RESET, GPIO_LOW);
mdelay(200);
gpio_set_value(BT_GPIO_RESET, GPIO_HIGH); /* bt reset deactive*/
mdelay(200);
#if BT_WAKE_HOST_SUPPORT
btWakeupHostLock();
#endif
pr_info("bt turn on power\n");
}
else {
#if BT_WAKE_HOST_SUPPORT
btWakeupHostUnlock();
#endif
if (!rk29sdk_wifi_power_state) {
gpio_set_value(BT_GPIO_POWER, GPIO_LOW); /* bt power off */
mdelay(20);
pr_info("bt shut off power\n");
}else {
pr_info("bt shouldn't shut off power, wifi is using it!\n");
}
gpio_set_value(BT_GPIO_RESET, GPIO_LOW); /* bt reset active*/
mdelay(20);
}
rk29sdk_bt_power_state = !blocked;
return 0;
}
static const struct rfkill_ops bcm4329_rfk_ops = {
.set_block = bcm4329_set_block,
};
static int __devinit bcm4329_rfkill_probe(struct platform_device *pdev)
{
int rc = 0;
bool default_state = true;
DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
/* default to bluetooth off */
bcm4329_set_block(NULL, default_state); /* blocked -> bt off */
gBtCtrl.bt_rfk = rfkill_alloc(bt_name,
NULL,
RFKILL_TYPE_BLUETOOTH,
&bcm4329_rfk_ops,
NULL);
if (!gBtCtrl.bt_rfk)
{
printk("fail to rfkill_allocate************\n");
return -ENOMEM;
}
rfkill_set_states(gBtCtrl.bt_rfk, default_state, false);
rc = rfkill_register(gBtCtrl.bt_rfk);
if (rc)
{
printk("failed to rfkill_register,rc=0x%x\n",rc);
rfkill_destroy(gBtCtrl.bt_rfk);
}
gpio_request(BT_GPIO_POWER, NULL);
gpio_request(BT_GPIO_RESET, NULL);
gpio_request(BT_GPIO_WAKE_UP, NULL);
#if BT_WAKE_HOST_SUPPORT
init_timer(&(gBtCtrl.tl));
gBtCtrl.tl.expires = jiffies + BT_WAKE_LOCK_TIMEOUT*HZ;
gBtCtrl.tl.function = timer_hostSleep;
add_timer(&(gBtCtrl.tl));
gBtCtrl.b_HostWake = false;
wake_lock_init(&(gBtCtrl.bt_wakelock), WAKE_LOCK_SUSPEND, "bt_wake");
rc = gpio_request(BT_GPIO_WAKE_UP_HOST, "bt_wake");
if (rc) {
printk("%s:failed to request RAHO_BT_WAKE_UP_HOST\n",__FUNCTION__);
}
IOMUX_BT_GPIO_WAKE_UP_HOST();
gpio_pull_updown(BT_GPIO_WAKE_UP_HOST,GPIOPullUp);
rc = request_irq(gpio_to_irq(BT_GPIO_WAKE_UP_HOST),bcm4329_wake_host_irq,IRQF_TRIGGER_FALLING,NULL,NULL);
if(rc)
{
printk("%s:failed to request RAHO_BT_WAKE_UP_HOST irq\n",__FUNCTION__);
gpio_free(BT_GPIO_WAKE_UP_HOST);
}
enable_irq_wake(gpio_to_irq(BT_GPIO_WAKE_UP_HOST)); // so RAHO_BT_WAKE_UP_HOST can wake up system
printk(KERN_INFO "bcm4329 module has been initialized,rc=0x%x\n",rc);
#endif
return rc;
}
static int __devexit bcm4329_rfkill_remove(struct platform_device *pdev)
{
if (gBtCtrl.bt_rfk)
rfkill_unregister(gBtCtrl.bt_rfk);
gBtCtrl.bt_rfk = NULL;
#if BT_WAKE_HOST_SUPPORT
del_timer(&(gBtCtrl.tl));//ɾ<><C9BE><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
btWakeupHostUnlock();
wake_lock_destroy(&(gBtCtrl.bt_wakelock));
#endif
platform_set_drvdata(pdev, NULL);
DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
return 0;
}
static struct platform_driver bcm4329_rfkill_driver = {
.probe = bcm4329_rfkill_probe,
.remove = __devexit_p(bcm4329_rfkill_remove),
.driver = {
.name = "rk29sdk_rfkill",
.owner = THIS_MODULE,
},
#if BT_WAKE_HOST_SUPPORT
.suspend = bcm4329_rfkill_suspend,
.resume = bcm4329_rfkill_resume,
#endif
};
/*
* Module initialization
*/
static int __init bcm4329_mod_init(void)
{
int ret;
DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
ret = platform_driver_register(&bcm4329_rfkill_driver);
printk("ret=0x%x\n", ret);
return ret;
}
static void __exit bcm4329_mod_exit(void)
{
platform_driver_unregister(&bcm4329_rfkill_driver);
}
module_init(bcm4329_mod_init);
module_exit(bcm4329_mod_exit);
MODULE_DESCRIPTION("bcm4329 Bluetooth driver");
MODULE_AUTHOR("roger_chen cz@rock-chips.com");
MODULE_LICENSE("GPL");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
#include <mach/key.h>
#include <mach/gpio.h>
#include <mach/board.h>
#define EV_ENCALL KEY_F4
#define EV_MENU KEY_F1
#define PRESS_LEV_LOW 1
#define PRESS_LEV_HIGH 0
static struct rk29_keys_button key_button[] = {
{
.desc = "menu",
.code = EV_MENU,
.gpio = RK29_PIN6_PA4,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "vol+",
.code = KEY_VOLUMEUP,
.gpio = RK29_PIN6_PA1,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "vol-",
.code = KEY_VOLUMEDOWN,
.gpio = RK29_PIN6_PA2,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "home",
.code = KEY_HOME,
.gpio = RK29_PIN6_PA3,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "esc",
.code = KEY_BACK,
.gpio = RK29_PIN6_PA0,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "sensor",
.code = KEY_CAMERA,
.gpio = RK29_PIN6_PA6,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "play",
.code = KEY_POWER,
.gpio = RK29_PIN6_PA7,
.active_low = PRESS_LEV_LOW,
//.code_long_press = EV_ENCALL,
.wakeup = 1,
},
#if 0
{
.desc = "vol+",
.code = KEY_VOLUMEDOWN,
.adc_value = 95,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "vol-",
.code = KEY_VOLUMEUP,
.adc_value = 249,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "menu",
.code = EV_MENU,
.adc_value = 406,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "home",
.code = KEY_HOME,
.code_long_press = KEY_F4,
.adc_value = 561,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "esc",
.code = KEY_ESC,
.adc_value = 726,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "adkey6",
.code = KEY_BACK,
.code_long_press = EV_ENCALL,
.adc_value = 899,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
#endif
};
struct rk29_keys_platform_data rk29_keys_pdata = {
.buttons = key_button,
.nbuttons = ARRAY_SIZE(key_button),
.chn = -1, //chn: 0-7, if do not use ADC,set 'chn' -1
};

View File

@@ -7,6 +7,11 @@
* Author:
* hcy@rock-chips.com
* yk@rock-chips.com
*
* v2.02
* reset DRAM DLL at update_mr
* adjust ZQCR0, MR0,MR1,MR2 for ODT and driver strengh
*
* v2.01
* disable DFTCMP
*/
@@ -261,6 +266,7 @@
#define DDR3_MR1_RTT_NOM(n) (((n&1)<<2)|((n&2)<<5)|((n&4)<<7))
//mr2 for ddr3
#define DDR3_MR2_RTT_WR(n) ((n&0x3)<<9)
#define DDR3_MR2_CWL(n) (((n-5)&0x7)<<3)
//EMR; //Extended Mode Register
@@ -532,7 +538,6 @@ static __sramdata uint32_t tWR_MR0;
static __sramdata uint32_t cl;
static __sramdata uint32_t cwl;
static __sramdata uint32_t cpu_freq;
static __sramdata uint32_t ddr_freq;
static __sramdata volatile uint32_t ddr_stop;
@@ -543,17 +548,17 @@ Cpu highest frequency is 1.2 GHz
1 cycle = 1/1.2 ns
1 us = 1000 ns = 1000 * 1.2 cycles = 1200 cycles
*****************************************************************************/
//static
void __sramlocalfunc delayus(uint32_t us)
{
uint32_t count;
if(cpu_freq == 24)
count = us * 6;//533;
else
count = us*200;
while(count--) // 3 cycles
barrier();
static __sramdata uint32_t loops_per_us;
#define LPJ_100MHZ 499728UL
/*static*/ void __sramlocalfunc delayus(uint32_t us)
{
uint32_t count;
count = loops_per_us*us;
while(count--) // 3 cycles
barrier();
}
static uint32_t __sramlocalfunc ddr_get_parameter(uint32_t nMHz)
@@ -926,7 +931,7 @@ static uint32_t __sramlocalfunc ddr_update_timing(void)
pDDR_Reg->TPR[1] = value | TFAW(tFAW);
// ddr3 tCKE should be tCKESR=tCKE+1nCK
pDDR_Reg->TPR[2] = TXS(tXS) | TXP(tXP) | TCKE(4);//0x198c8;//
pDDR_Reg->ZQCR[0] = 0x10039d29;//(pDDR_Reg->ZQSR & (0x3FF)) | (0x6<<10) | (0x6<<15) | (0x1<<28);
}
else if(mem_type == DDRII)
{
@@ -965,9 +970,20 @@ static uint32_t __sramlocalfunc ddr_update_mr(void)
if(mem_type == DDR3)
{
pDDR_Reg->TPR3 = value | CL(cl) | CWL(cwl) | WR(tWR);
pDDR_Reg->MR = DDR3_BL8 | DDR3_CL(cl) | DDR3_MR0_WR(tWR_MR0)/*15 ns*/;
pDDR_Reg->MR = DDR3_BL8 | DDR3_CL(cl) | DDR3_MR0_DLL_RESET | DDR3_MR0_WR(tWR_MR0)/*15 ns*/;
delayus(1);
pDDR_Reg->EMR2 = DDR3_MR2_CWL(cwl);
/*
* DIC:Output Driver Impedance Control,0, RZQ(240)/6
* Rtt_Nom:2 RZQ(240)/2
*/
pDDR_Reg->EMR = DDR3_MR1_DIC(0) | DDR3_MR1_AL(0) | DDR3_MR1_RTT_NOM(2);
delayus(1);
/* DDR3 :CWL=5
* RTT_WR: 1, RZQ(240)/4
*/
pDDR_Reg->EMR2 = DDR3_MR2_RTT_WR(1)|DDR3_MR2_CWL(cwl);
delayus(1);
pDDR_Reg->EMR3 = 0x0;
}
else if(mem_type == DDRII)
{
@@ -1047,7 +1063,7 @@ static uint32_t __sramlocalfunc ddr_set_pll(uint32_t nMHz, uint32_t set)
delayus(1); //delay at least 500ns
pSCU_Reg->CRU_DPLL_CON &= ~(0x1<<15);
delayus(2000); // 7.2us*140=1.008ms
delayus(500); // wait for DPLL stable
// ddr pll normal
pSCU_Reg->CRU_MODE_CON |= 0x1<<6;
@@ -1087,7 +1103,7 @@ void __sramlocalfunc ddr_selfrefresh_enter(void)
pSCU_Reg->CRU_SOFTRST_CON[0] |= (0x1F<<19); //reset DLL
delayus(1);
pSCU_Reg->CRU_CLKGATE_CON[0] |= (0x1<<18); //close DDR PHY clock
delayus(10);
delayus(1);
pDDR_Reg->DLLCR09[0] =0x80000000;
pDDR_Reg->DLLCR09[9] =0x80000000;
pDDR_Reg->DLLCR09[1] =0x80000000;
@@ -1105,13 +1121,13 @@ void __sramlocalfunc ddr_selfrefresh_exit(void)
6. Re-enables all host ports
*/
pSCU_Reg->CRU_CLKGATE_CON[0] &= ~(0x1<<18); //open DDR PHY clock
delayus(10);
delayus(1);
pSCU_Reg->CRU_SOFTRST_CON[0] &= ~(0x1F<<19); //de-reset DLL
delayus(1000);
delayus(10);
pDDR_Reg->CCR &= ~ITMRST; //ITM reset
delayus(500);
delayus(5);
pDDR_Reg->DCR = (pDDR_Reg->DCR & (~((0x1<<24) | (0x1<<13) | (0xF<<27) | (0x1<<31)))) | ((0x1<<13) | (0x7<<27) | (0x1<<31)); //exit
delayus(1000);
delayus(10);
ddr_update_mr();
delayus(1);
@@ -1120,8 +1136,8 @@ refresh:
pDDR_Reg->DRR |= RD;
delayus(1);
pDDR_Reg->CCR |= DTT;
//delayus(15);
dsb();
delayus(10);
do
{
delayus(1);
@@ -1148,16 +1164,22 @@ uint32_t __sramfunc ddr_change_freq(uint32_t nMHz)
volatile u32 n;
unsigned long flags;
volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;
uint32_t regvalue = pSCU_Reg->CRU_APLL_CON;
uint32_t freq;
if((pSCU_Reg->CRU_MODE_CON & 0x03) == 0x03)
cpu_freq = 24;
else
cpu_freq = clk_get_rate(clk_get(NULL,"core"))/1000000;
// freq = (Fin/NR)*NF/OD
if((pSCU_Reg->CRU_MODE_CON&3) == 1) // CPLL Normal mode
freq = 24 *((((regvalue>>3)&0x7f)+1)<<1) // NF = 2*(CLKF+1)
/(((regvalue>>10)&0x1f)+1) // NR = CLKR+1
*(2<<((regvalue>>1)&3)); // OD = 2^CLKOD
else
freq = 24;
loops_per_us = LPJ_100MHZ*freq / 1000000;
ret = ddr_set_pll(nMHz, 0);
ddr_get_parameter(ret);
/** 1. Make sure there is no host access */
#if 1
local_irq_save(flags);
flush_cache_all();
__cpuc_flush_kern_all();
@@ -1175,7 +1197,6 @@ uint32_t __sramfunc ddr_change_freq(uint32_t nMHz)
n= pDDR_Reg->CCR;
n= pSCU_Reg->CRU_SOFTRST_CON[0];
dsb();
#endif
/** 2. ddr enter self-refresh mode or precharge power-down mode */
ddr_selfrefresh_enter();
@@ -1237,9 +1258,19 @@ void __sramfunc ddr_suspend(void)
{
uint32_t n;
volatile unsigned int * temp=(volatile unsigned int *)SRAM_CODE_OFFSET;
uint32_t regvalue = pSCU_Reg->CRU_APLL_CON;
uint32_t freq;
// freq = (Fin/NR)*NF/OD
if((pSCU_Reg->CRU_MODE_CON&3) == 1) // CPLL Normal mode
freq = 24 *((((regvalue>>3)&0x7f)+1)<<1) // NF = 2*(CLKF+1)
/(((regvalue>>10)&0x1f)+1) // NR = CLKR+1
*(2<<((regvalue>>1)&3)); // OD = 2^CLKOD
else
freq = 24;
loops_per_us = LPJ_100MHZ*freq / 1000000;
cpu_freq = 24;
/** 1. Make sure there is no host access */
flush_cache_all();
__cpuc_flush_kern_all();
@@ -1321,10 +1352,12 @@ void __sramfunc ddr_resume(void)
delayus(1);
#endif
#if 1
pSCU_Reg->CRU_DPLL_CON &= ~(0x1 << 15); //power on DPLL
// while(!(pGRF_Reg->GRF_SOC_CON[0] & (1<<28)));
delayus(500); // 7.2us*140=1.008ms // <20><><EFBFBD><EFBFBD>pll
pSCU_Reg->CRU_DPLL_CON &= ~(0x1 << 15); //power on DPLL
delayus(300); // <20><><EFBFBD><EFBFBD>pll
do
{
delayus(3);
}while(!(pGRF_Reg->GRF_SOC_CON[0] & (1<<28))); //wait pll lock
// ddr pll normal
value = pSCU_Reg->CRU_MODE_CON;
value &=~(0x3<<6);
@@ -1338,7 +1371,6 @@ void __sramfunc ddr_resume(void)
pSCU_Reg->CRU_CLKGATE_CON[1] &= ~(0x1<<6); //close DDR PERIPH AXI clock
pSCU_Reg->CRU_CLKGATE_CON[0] &= ~(0x1<<18); //enable DDR PHY clock
delayus(1);
#endif
ddr_selfrefresh_exit();
dsb();
@@ -1372,7 +1404,6 @@ typedef struct _dtt_cnt_t
uint32_t cnt;
}dtt_cnt_t;
//static int __init ddr_probe(void)
int ddr_init(uint32_t dram_type, uint32_t freq)
{
volatile uint32_t value = 0;
@@ -1383,7 +1414,7 @@ int ddr_init(uint32_t dram_type, uint32_t freq)
uint32_t bank = 0;
uint32_t n;
ddr_print("version 2.01 20110504 \n");
ddr_print("version 2.02 20111109 \n");
mem_type = (pDDR_Reg->DCR & 0x3);
ddr_type = dram_type;//DDR3_TYPE;//
@@ -1450,6 +1481,8 @@ int ddr_init(uint32_t dram_type, uint32_t freq)
}
pDDR_Reg->DTAR = value;
pDDR_Reg->CCR &= ~(DFTCMP);
pDDR_Reg->IOCR = AUTO_CMD_IOPD(3) | AUTO_DATA_IOPD(3) | DQ_ODT | DQS_ODT | DQRTT | DQSRTT;
//pDDR_Reg->CCR |= DQSCFG;// passive windowing mode
if((mem_type == DDRII) || (mem_type == DDR3))
@@ -1492,8 +1525,6 @@ int ddr_init(uint32_t dram_type, uint32_t freq)
}
EXPORT_SYMBOL(ddr_init);
//core_initcall_sync(ddr_probe);
#ifdef CONFIG_DDR_RECONFIG
#include "ddr_reconfig.c"
#endif

View File

@@ -221,6 +221,16 @@ struct platform_device rk29_device_backlight = {
}
};
#endif
#ifdef CONFIG_BUTTON_LIGHT
struct platform_device rk29_device_buttonlight = {
.name = "rk29_button_light",
.id = -1,
.dev = {
.platform_data = &rk29_button_light_info,
}
};
#endif
#ifdef CONFIG_SDMMC0_RK29
#ifndef CONFIG_EMMC_RK29
static struct resource resources_sdmmc0[] = {

View File

@@ -65,7 +65,9 @@ extern struct platform_device rk29_device_sdmmc1;
extern struct platform_device rk29_device_adc;
extern struct platform_device rk29_device_vmac;
extern struct rk29_bl_info rk29_bl_info;
extern struct rk29_button_light_info rk29_button_light_info;
extern struct platform_device rk29_device_backlight;
extern struct platform_device rk29_device_buttonlight;
extern struct platform_device rk29_device_usb20_otg;
extern struct platform_device rk29_device_usb20_host;
extern struct platform_device rk29_device_usb11_host;

View File

@@ -248,6 +248,17 @@ struct mma8452_platform_data {
int (*mma8452_platform_wakeup)(void);
void (*exit_platform_hw)(void);
};
struct bma023_platform_data {
u16 model;
u16 swap_xy;
u16 swap_xyz;
signed char orientation[9];
int (*get_pendown_state)(void);
int (*init_platform_hw)(void);
int (*mma8452_platform_sleep)(void);
int (*mma8452_platform_wakeup)(void);
void (*exit_platform_hw)(void);
};
struct cm3202_platform_data {
int CM3202_SD_IOPIN;
@@ -274,6 +285,9 @@ struct ft5406_platform_data {
};
struct goodix_platform_data {
int model ;
int rest_pin;
int irq_pin ;
int (*get_pendown_state)(void);
int (*init_platform_hw)(void);
int (*platform_sleep)(void);

View File

@@ -160,6 +160,7 @@ struct rk29camera_gpio_res {
unsigned int gpio_flash;
unsigned int gpio_flag;
unsigned int gpio_init;
unsigned int orientation;
const char *dev_name;
};

View File

@@ -157,28 +157,21 @@ void __sramfunc ddr_testmode(void)
{
for (;;)
{
sram_printch(' ');
sram_printch('8');
sram_printch('8');
sram_printch('8');
sram_printch(' ');
sram_printascii("change freq\n");
g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
nMHz = 333 + (random32()>>25);
if(nMHz > 402)
nMHz = 402;
nMHz = 333 + random32();
nMHz %= 490;
if(nMHz < 100)
nMHz = 100;
nMHz = ddr_change_freq(nMHz);
printhex(nMHz);
sram_printch(' ');
printhex(n++);
//ddr_print("%s change freq to: %d MHz\n", __func__, nMHz);
ddr_change_freq(nMHz);
sram_printch(' ');
g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
if (g_crc1!=g_crc2)
{
sram_printch(' ');
sram_printch('f');
sram_printch('a');
sram_printch('i');
sram_printch('l');
sram_printascii("fail\n");
}
//ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
// sram_printascii("change freq success\n");
@@ -253,7 +246,7 @@ static void __sramfunc rk29_sram_suspend(void)
{
u32 vol;
if ((ddr_debug == 1) || (ddr_debug == 2))
if (ddr_debug == 2)
ddr_testmode();
sram_printch('5');
@@ -418,7 +411,7 @@ static int rk29_pm_enter(suspend_state_t state)
#endif
// memory teseter
if (ddr_debug == 3)
if (ddr_debug != 2)
ddr_testmode();
// dump GPIO INTEN for debug

View File

@@ -7,7 +7,21 @@
#include <asm/io.h>
#include <mach/gpio.h>
#include <asm/vfp.h>
#if 1
void __sramfunc sram_printch(char byte);
void __sramfunc printhex(unsigned int hex);
#define sram_printHX(a)
#else
#define sram_printch(a)
#define sram_printHX(a)
#endif
#define grf_readl(offset) readl(RK29_GRF_BASE + offset)
#define grf_writel(v, offset) do { writel(v, RK29_GRF_BASE + offset); readl(RK29_GRF_BASE + offset); } while (0)
#define sram_udelay(usecs,a) LOOP((usecs)*LOOPS_PER_USEC)
#if defined(CONFIG_RK29_SPI_INSRAM)
@@ -17,7 +31,7 @@
#define SPI_SR_SPEED (2*SPI_MHZ)
#if defined(CONFIG_MACH_RK29_A22)||defined(CONFIG_MACH_RK29_PHONESDK)
#if defined(CONFIG_MACH_RK29_A22)||defined(CONFIG_MACH_RK29_PHONESDK)||defined(CONFIG_MACH_RK29_TD8801_V2)
#define SRAM_SPI_CH 1
#define SRAM_SPI_CS 1
@@ -85,15 +99,6 @@ SPI_BAUDR,
SPI_SER,
DATE_END,
};
#if 1
void __sramfunc sram_printch(char byte);
void __sramfunc printhex(unsigned int hex);
#define sram_printHX(a)
#else
#define sram_printch(a)
#define sram_printHX(a)
#endif
static u32 __sramdata spi_data[DATE_END]={};
#define sram_spi_dis() spi_writel(spi_readl(SPIM_ENR)&~(0x1<<0),SPIM_ENR)
@@ -105,10 +110,6 @@ void __sramfunc printhex(unsigned int hex);
#define spi_readl(offset) readl(SRAM_SPI_ADDRBASE + offset)
#define spi_writel(v, offset) writel(v, SRAM_SPI_ADDRBASE+ offset)
#define grf_readl(offset) readl(RK29_GRF_BASE + offset)
#define grf_writel(v, offset) do { writel(v, RK29_GRF_BASE + offset); readl(RK29_GRF_BASE + offset); } while (0)
#define sram_udelay(usecs,a) LOOP((usecs)*LOOPS_PER_USEC)
#define SPI_GATE1_MASK 0xCF
@@ -362,6 +363,10 @@ void __sramfunc rk29_suspend_voltage_resume(unsigned int vol)
#endif
/*******************************************gpio*********************************************/
#ifdef CONFIG_RK29_CLK_SWITCH_TO_32K
#define PM_GETGPIO_BASE(N) RK29_GPIO##N##_BASE
#define PM_GPIO_DR 0
#define PM_GPIO_DDR 0x4
#define PM_GPIO_INTEN 0x30
__sramdata u32 pm_gpio_base[7]=
{
RK29_GPIO0_BASE,
@@ -410,10 +415,240 @@ void __sramfunc pm_gpio_set(unsigned gpio,eGPIOPinDirection_t direction,eGPIOPin
}
}
#endif
/*****************************************gpio ctr*********************************************/
#if defined(CONFIG_RK29_GPIO_SUSPEND)
#define GRF_GPIO0_DIR 0x000
#define GRF_GPIO1_DIR 0x004
#define GRF_GPIO2_DIR 0x008
#define GRF_GPIO3_DIR 0x00c
#define GRF_GPIO4_DIR 0x010
#define GRF_GPIO5_DIR 0x014
#define GRF_GPIO0_DO 0x018
#define GRF_GPIO1_DO 0x01c
#define GRF_GPIO2_DO 0x020
#define GRF_GPIO3_DO 0x024
#define GRF_GPIO4_DO 0x028
#define GRF_GPIO5_DO 0x02c
#define GRF_GPIO0_EN 0x030
#define GRF_GPIO1_EN 0x034
#define GRF_GPIO2_EN 0x038
#define GRF_GPIO3_EN 0x03c
#define GRF_GPIO4_EN 0x040
#define GRF_GPIO5_EN 0x044
#define GRF_GPIO0L_IOMUX 0x048
#define GRF_GPIO0H_IOMUX 0x04c
#define GRF_GPIO1L_IOMUX 0x050
#define GRF_GPIO1H_IOMUX 0x054
#define GRF_GPIO2L_IOMUX 0x058
#define GRF_GPIO2H_IOMUX 0x05c
#define GRF_GPIO3L_IOMUX 0x060
#define GRF_GPIO3H_IOMUX 0x064
#define GRF_GPIO4L_IOMUX 0x068
#define GRF_GPIO4H_IOMUX 0x06c
#define GRF_GPIO5L_IOMUX 0x070
#define GRF_GPIO5H_IOMUX 0x074
typedef struct GPIO_IOMUX
{
unsigned int GPIOL_IOMUX;
unsigned int GPIOH_IOMUX;
}GPIO_IOMUX_PM;
//GRF Registers
typedef struct REG_FILE_GRF
{
unsigned int GRF_GPIO_DIR[6];
unsigned int GRF_GPIO_DO[6];
unsigned int GRF_GPIO_EN[6];
GPIO_IOMUX_PM GRF_GPIO_IOMUX[6];
unsigned int GRF_GPIO_PULL[7];
} GRF_REG_SAVE;
static GRF_REG_SAVE pm_grf;
int __sramdata crumode;
u32 __sramdata gpio2_pull,gpio6_pull;
//static GRF_REG_SAVE __sramdata pm_grf;
static void pm_keygpio_prepare(void)
{
gpio6_pull = grf_readl(GRF_GPIO6_PULL);
gpio2_pull = grf_readl(GRF_GPIO2_PULL);
}
void pm_keygpio_sdk_suspend(void)
{
pm_keygpio_prepare();
grf_writel(gpio6_pull|0x7f,GRF_GPIO6_PULL);//key pullup/pulldown disable
grf_writel(gpio2_pull|0x00000f30,GRF_GPIO2_PULL);
}
void pm_keygpio_sdk_resume(void)
{
grf_writel(gpio6_pull,GRF_GPIO6_PULL);//key pullup/pulldown enable
grf_writel(gpio2_pull,GRF_GPIO2_PULL);
}
void pm_keygpio_a22_suspend(void)
{
pm_keygpio_prepare();
grf_writel(gpio6_pull|0x7f,GRF_GPIO6_PULL);//key pullup/pulldown disable
grf_writel(gpio2_pull|0x00000900,GRF_GPIO2_PULL);
}
void pm_keygpio_a22_resume(void)
{
grf_writel(gpio6_pull,GRF_GPIO6_PULL);//key pullup/pulldown enable
grf_writel(gpio2_pull,GRF_GPIO2_PULL);
}
static void pm_spi_gpio_prepare(void)
{
pm_grf.GRF_GPIO_IOMUX[1].GPIOL_IOMUX = grf_readl(GRF_GPIO1L_IOMUX);
pm_grf.GRF_GPIO_IOMUX[2].GPIOH_IOMUX = grf_readl(GRF_GPIO2H_IOMUX);
pm_grf.GRF_GPIO_PULL[1] = grf_readl(GRF_GPIO1_PULL);
pm_grf.GRF_GPIO_PULL[2] = grf_readl(GRF_GPIO2_PULL);
pm_grf.GRF_GPIO_EN[1] = grf_readl(GRF_GPIO1_EN);
pm_grf.GRF_GPIO_EN[2] = grf_readl(GRF_GPIO2_EN);
}
void pm_spi_gpio_suspend(void)
{
int io1L_iomux;
int io2H_iomux;
int io1_pull,io2_pull;
int io1_en,io2_en;
pm_spi_gpio_prepare();
io1L_iomux = grf_readl(GRF_GPIO1L_IOMUX);
io2H_iomux = grf_readl(GRF_GPIO2H_IOMUX);
grf_writel(io1L_iomux&(~((0x03<<6)|(0x03 <<8))), GRF_GPIO1L_IOMUX);
grf_writel(io2H_iomux&0xffff0000, GRF_GPIO2H_IOMUX);
io1_pull = grf_readl(GRF_GPIO1_PULL);
io2_pull = grf_readl(GRF_GPIO2_PULL);
grf_writel(io1_pull|0x18,GRF_GPIO1_PULL);
grf_writel(io2_pull|0x00ff0000,GRF_GPIO2_PULL);
io1_en = grf_readl(GRF_GPIO1_EN);
io2_en = grf_readl(GRF_GPIO2_EN);
grf_writel(io1_en|0x18,GRF_GPIO1_EN);
grf_writel(io2_en|0x00ff0000,GRF_GPIO2_EN);
}
void pm_spi_gpio_resume(void)
{
grf_writel(pm_grf.GRF_GPIO_EN[1],GRF_GPIO1_EN);
grf_writel(pm_grf.GRF_GPIO_EN[2],GRF_GPIO2_EN);
grf_writel(pm_grf.GRF_GPIO_PULL[1],GRF_GPIO1_PULL);
grf_writel(pm_grf.GRF_GPIO_PULL[2],GRF_GPIO2_PULL);
grf_writel(pm_grf.GRF_GPIO_IOMUX[1].GPIOL_IOMUX, GRF_GPIO1L_IOMUX);
grf_writel(pm_grf.GRF_GPIO_IOMUX[2].GPIOH_IOMUX, GRF_GPIO2H_IOMUX);
}
void pm_gpio_suspend(void)
{
pm_spi_gpio_suspend(); // spi pullup/pulldown disable....
#if defined(CONFIG_MACH_RK29_PHONESDK)
{ pm_keygpio_sdk_suspend();// key pullup/pulldown disable.....
}
#endif
#if defined(CONFIG_MACH_RK29_A22)
{ pm_keygpio_a22_suspend();// key pullup/pulldown disable.....
}
#endif
}
void pm_gpio_resume(void)
{
pm_spi_gpio_resume(); // spi pullup/pulldown enable.....
#if defined(CONFIG_MACH_RK29_PHONESDK)
{ pm_keygpio_sdk_resume();// key pullup/pulldown enable.....
}
#endif
#if defined(CONFIG_MACH_RK29_A22)
{ pm_keygpio_a22_resume();// key pullup/pulldown enable.....
}
#endif
}
#else
void pm_gpio_suspend(void)
{}
void pm_gpio_resume(void)
{}
#endif
/*************************************neon powerdomain******************************/
#define vfpreg(_vfp_) #_vfp_
#define fmrx(_vfp_) ({ \
u32 __v; \
asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \
: "=r" (__v) : : "cc"); \
__v; \
})
#define fmxr(_vfp_,_var_) \
asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \
: : "r" (_var_) : "cc")
#define pmu_read(offset) readl(RK29_PMU_BASE + (offset))
#define pmu_write(offset, value) writel((value), RK29_PMU_BASE + (offset))
#define PMU_PG_CON 0x10
extern void vfp_save_state(void *location, u32 fpexc);
extern void vfp_load_state(void *location, u32 fpexc);
static u64 __sramdata saveptr[33]={};
void neon_powerdomain_off(void)
{
int ret,i=0;
int *p;
p=&saveptr;
unsigned int fpexc = fmrx(FPEXC); //get neon Logic gate
fmxr(FPEXC, fpexc | FPEXC_EN); //open neon Logic gate
for(i=0;i<34;i++){
vfp_save_state(p,fpexc); //save neon reg,32 D reg,2 control reg
p++;
}
fmxr(FPEXC, fpexc & ~FPEXC_EN); //close neon Logic gate
ret=pmu_read(PMU_PG_CON); //get power domain state
pmu_write(PMU_PG_CON,ret|(0x1<<1)); //powerdomain off neon
}
void neon_powerdomain_on(void)
{
int ret,i=0;
int *p;
p=&saveptr;
ret=pmu_read(PMU_PG_CON); //get power domain state
pmu_write(PMU_PG_CON,ret&~(0x1<<1)); //powerdomain on neon
sram_udelay(5000,24);
unsigned int fpexc = fmrx(FPEXC); //get neon Logic gate
fmxr(FPEXC, fpexc | FPEXC_EN); //open neon Logic gate
for(i=0;i<34;i++){
vfp_load_state(p,fpexc); //recovery neon reg, 32 D reg,2 control reg
p++;
}
fmxr(FPEXC, fpexc | FPEXC_EN); //open neon Logic gate
}
/*************************************************32k**************************************/
#ifdef CONFIG_RK29_CLK_SWITCH_TO_32K
static int __sramdata crumode;
//static int __sramdata crumode;
void __sramfunc pm_clk_switch_32k(void)
{
int vol;

View File

@@ -6,7 +6,6 @@
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/smp_lock.h>
#define CMMB_MAJOR 200
@@ -54,4 +53,4 @@ void cmmb_unregister_device(struct cmmb_device *cmmbdev);
FUNCTION(ARGS); \
#endif/* #ifndef _CMMB_CLASS_H_ */
#endif/* #ifndef _CMMB_CLASS_H_ */

View File

@@ -4,6 +4,8 @@
#include <linux/workqueue.h>
#include <asm/atomic.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#if 1
#define DBGERR(x...) printk(KERN_INFO x)
#else

View File

@@ -37,6 +37,7 @@
#include "smsendian.h"
#include "sms-cards.h"
#include <mach/gpio.h>
#include <linux/slab.h>
#define MAX_GPIO_PIN_NUMBER 31

View File

@@ -42,5 +42,8 @@ int smsspibus_ssp_resume(void* context);
unsigned int cmmb_pw_rst;
unsigned int cmmb_irq;
void (*io_init_mux)(void);
void (*cmmb_io_pm)(void);
void (*cmmb_power_on)(void);
void (*cmmb_power_down)(void);
};
#endif /* __SMS_SPI_PHY_H__ */

View File

@@ -39,6 +39,7 @@
#include <linux/earlysuspend.h>
#include <linux/gpio.h>
#include <mach/board.h>
#include <linux/slab.h>
/* Debug */
#if 1
@@ -60,8 +61,11 @@
#define enable 1
#define disable 0
extern int wm8994_set_status(void);
/*#ifdef CONFIG_SND_SOC_WM8994
extern int wm8994_set_status(void);
#endif
*/
/* headset private data */
struct headset_priv {
struct input_dev *input_dev;
@@ -258,13 +262,13 @@ static void Hook_work(struct work_struct *work)
DBG("Headset is out\n");
goto RE_ERROR;
}
#ifdef CONFIG_SND_SOC_WM8994
/*#ifdef CONFIG_SND_SOC_WM8994
if(wm8994_set_status() < 0)
{
DBG("wm8994 is not set on heatset channel or suspend\n");
goto RE_ERROR;
}
#endif
#endif*/
for(i=0; i<3; i++)
{
level = gpio_get_value(pdata->Hook_gpio);
@@ -325,7 +329,7 @@ static void headset_timer_callback(unsigned long arg)
DBG("Headset is out\n");
goto out;
}
#ifdef CONFIG_SND_SOC_WM8994
/*#ifdef CONFIG_SND_SOC_WM8994
if(wm8994_set_status() < 0)
{
DBG("wm8994 is not set on heatset channel\n");
@@ -333,7 +337,7 @@ static void headset_timer_callback(unsigned long arg)
add_timer(&headset_info->headset_timer);
goto out;
}
#endif
#endif*/
for(i=0; i<3; i++)
{
level = gpio_get_value(pdata->Hook_gpio);

View File

@@ -53,4 +53,11 @@ config GS_L3G4200D
To have support for your specific gsesnor you will have to
select the proper drivers which depend on this option.
config GS_BMA023
bool "gs_bma023"
depends on G_SENSOR_DEVICE
default n
help
To have support for your specific gsesnor you will have to
select the proper drivers which depend on this option.
endif

View File

@@ -4,4 +4,5 @@ obj-$(CONFIG_GS_MMA7660) += mma7660.o
obj-$(CONFIG_GS_MMA8452) += mma8452.o
obj-$(CONFIG_GS_L3G4200D) += l3g4200d.o
obj-$(CONFIG_GS_KXTF9) += kxtf9.o
obj-$(CONFIG_GS_LIS3DH) += lis3dh_acc_misc.o
obj-$(CONFIG_GS_LIS3DH) += lis3dh_acc_misc.o
obj-$(CONFIG_GS_BMA023) += bma023.o

View File

@@ -0,0 +1,920 @@
/* drivers/i2c/chips/bma023.c - bma023 compass driver
*
* Copyright (C) 2007-2008 HTC Corporation.
* Author: Hou-Kun Chen <houkun.chen@gmail.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
#include <linux/freezer.h>
#include <mach/gpio.h>
#include <mach/board.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#define SENSOR_NAME "bma150"
#define GRAVITY_EARTH 9806550
#define ABSMIN_2G (-GRAVITY_EARTH * 2)
#define ABSMAX_2G (GRAVITY_EARTH * 2)
#define BMA150_MAX_DELAY 200
#define BMA150_CHIP_ID 2
#define BMA150_RANGE_SET 0
#define BMA150_BW_SET 4
#define BMA150_CHIP_ID_REG 0x00
#define BMA150_X_AXIS_LSB_REG 0x02
#define BMA150_X_AXIS_MSB_REG 0x03
#define BMA150_Y_AXIS_LSB_REG 0x04
#define BMA150_Y_AXIS_MSB_REG 0x05
#define BMA150_Z_AXIS_LSB_REG 0x06
#define BMA150_Z_AXIS_MSB_REG 0x07
#define BMA150_STATUS_REG 0x09
#define BMA150_CTRL_REG 0x0a
#define BMA150_CONF1_REG 0x0b
#define BMA150_CUSTOMER1_REG 0x12
#define BMA150_CUSTOMER2_REG 0x13
#define BMA150_RANGE_BWIDTH_REG 0x14
#define BMA150_CONF2_REG 0x15
#define BMA150_OFFS_GAIN_X_REG 0x16
#define BMA150_OFFS_GAIN_Y_REG 0x17
#define BMA150_OFFS_GAIN_Z_REG 0x18
#define BMA150_OFFS_GAIN_T_REG 0x19
#define BMA150_OFFSET_X_REG 0x1a
#define BMA150_OFFSET_Y_REG 0x1b
#define BMA150_OFFSET_Z_REG 0x1c
#define BMA150_OFFSET_T_REG 0x1d
#define BMA150_CHIP_ID__POS 0
#define BMA150_CHIP_ID__MSK 0x07
#define BMA150_CHIP_ID__LEN 3
#define BMA150_CHIP_ID__REG BMA150_CHIP_ID_REG
/* DATA REGISTERS */
#define BMA150_NEW_DATA_X__POS 0
#define BMA150_NEW_DATA_X__LEN 1
#define BMA150_NEW_DATA_X__MSK 0x01
#define BMA150_NEW_DATA_X__REG BMA150_X_AXIS_LSB_REG
#define BMA150_ACC_X_LSB__POS 6
#define BMA150_ACC_X_LSB__LEN 2
#define BMA150_ACC_X_LSB__MSK 0xC0
#define BMA150_ACC_X_LSB__REG BMA150_X_AXIS_LSB_REG
#define BMA150_ACC_X_MSB__POS 0
#define BMA150_ACC_X_MSB__LEN 8
#define BMA150_ACC_X_MSB__MSK 0xFF
#define BMA150_ACC_X_MSB__REG BMA150_X_AXIS_MSB_REG
#define BMA150_ACC_Y_LSB__POS 6
#define BMA150_ACC_Y_LSB__LEN 2
#define BMA150_ACC_Y_LSB__MSK 0xC0
#define BMA150_ACC_Y_LSB__REG BMA150_Y_AXIS_LSB_REG
#define BMA150_ACC_Y_MSB__POS 0
#define BMA150_ACC_Y_MSB__LEN 8
#define BMA150_ACC_Y_MSB__MSK 0xFF
#define BMA150_ACC_Y_MSB__REG BMA150_Y_AXIS_MSB_REG
#define BMA150_ACC_Z_LSB__POS 6
#define BMA150_ACC_Z_LSB__LEN 2
#define BMA150_ACC_Z_LSB__MSK 0xC0
#define BMA150_ACC_Z_LSB__REG BMA150_Z_AXIS_LSB_REG
#define BMA150_ACC_Z_MSB__POS 0
#define BMA150_ACC_Z_MSB__LEN 8
#define BMA150_ACC_Z_MSB__MSK 0xFF
#define BMA150_ACC_Z_MSB__REG BMA150_Z_AXIS_MSB_REG
/* CONTROL BITS */
#define BMA150_SLEEP__POS 0
#define BMA150_SLEEP__LEN 1
#define BMA150_SLEEP__MSK 0x01
#define BMA150_SLEEP__REG BMA150_CTRL_REG
#define BMA150_SOFT_RESET__POS 1
#define BMA150_SOFT_RESET__LEN 1
#define BMA150_SOFT_RESET__MSK 0x02
#define BMA150_SOFT_RESET__REG BMA150_CTRL_REG
#define BMA150_EE_W__POS 4
#define BMA150_EE_W__LEN 1
#define BMA150_EE_W__MSK 0x10
#define BMA150_EE_W__REG BMA150_CTRL_REG
#define BMA150_UPDATE_IMAGE__POS 5
#define BMA150_UPDATE_IMAGE__LEN 1
#define BMA150_UPDATE_IMAGE__MSK 0x20
#define BMA150_UPDATE_IMAGE__REG BMA150_CTRL_REG
#define BMA150_RESET_INT__POS 6
#define BMA150_RESET_INT__LEN 1
#define BMA150_RESET_INT__MSK 0x40
#define BMA150_RESET_INT__REG BMA150_CTRL_REG
/* BANDWIDTH dependend definitions */
#define BMA150_BANDWIDTH__POS 0
#define BMA150_BANDWIDTH__LEN 3
#define BMA150_BANDWIDTH__MSK 0x07
#define BMA150_BANDWIDTH__REG BMA150_RANGE_BWIDTH_REG
/* RANGE */
#define BMA150_RANGE__POS 3
#define BMA150_RANGE__LEN 2
#define BMA150_RANGE__MSK 0x18
#define BMA150_RANGE__REG BMA150_RANGE_BWIDTH_REG
/* WAKE UP */
#define BMA150_WAKE_UP__POS 0
#define BMA150_WAKE_UP__LEN 1
#define BMA150_WAKE_UP__MSK 0x01
#define BMA150_WAKE_UP__REG BMA150_CONF2_REG
#define BMA150_WAKE_UP_PAUSE__POS 1
#define BMA150_WAKE_UP_PAUSE__LEN 2
#define BMA150_WAKE_UP_PAUSE__MSK 0x06
#define BMA150_WAKE_UP_PAUSE__REG BMA150_CONF2_REG
#define BMA150_GET_BITSLICE(regvar, bitname)\
((regvar & bitname##__MSK) >> bitname##__POS)
#define BMA150_SET_BITSLICE(regvar, bitname, val)\
((regvar & ~bitname##__MSK) | ((val<<bitname##__POS)&bitname##__MSK))
/* range and bandwidth */
#define BMA150_RANGE_2G 0
#define BMA150_RANGE_4G 1
#define BMA150_RANGE_8G 2
#define BMA150_BW_25HZ 0
#define BMA150_BW_50HZ 1
#define BMA150_BW_100HZ 2
#define BMA150_BW_190HZ 3
#define BMA150_BW_375HZ 4
#define BMA150_BW_750HZ 5
#define BMA150_BW_1500HZ 6
/* mode settings */
#define BMA150_MODE_NORMAL 0
#define BMA150_MODE_SLEEP 2
#define BMA150_MODE_WAKE_UP 3
struct bma150acc{
s16 x,
y,
z;
} ;
static struct {
int x;
int y;
int z;
}sense_data;
struct bma150_data {
struct i2c_client *bma150_client;
atomic_t delay;
atomic_t enable;
unsigned char mode;
struct input_dev *input;
struct bma150acc value;
struct mutex value_mutex;
struct mutex enable_mutex;
struct mutex mode_mutex;
struct delayed_work work;
struct work_struct irq_work;
struct early_suspend early_suspend;
};
#define RBUFF_SIZE 12 /* Rx buffer size */
#define BMAIO 0xA1
/* IOCTLs for MMA8452 library */
#define BMA_IOCTL_INIT _IO(BMAIO, 0x01)
#define BMA_IOCTL_RESET _IO(BMAIO, 0x04)
#define BMA_IOCTL_CLOSE _IO(BMAIO, 0x02)
#define BMA_IOCTL_START _IO(BMAIO, 0x03)
#define BMA_IOCTL_GETDATA _IOR(BMAIO, 0x08, char[RBUFF_SIZE+1])
static int bma023_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg);
static void bma150_early_suspend(struct early_suspend *h);
static void bma150_late_resume(struct early_suspend *h);
static int bma150_smbus_read_byte(struct i2c_client *client,
unsigned char reg_addr, unsigned char *data)
{
s32 dummy;
dummy = i2c_smbus_read_byte_data(client, reg_addr);
if (dummy < 0)
return -1;
*data = dummy & 0x000000ff;
return 0;
}
static int bma150_smbus_write_byte(struct i2c_client *client,
unsigned char reg_addr, unsigned char *data)
{
s32 dummy;
dummy = i2c_smbus_write_byte_data(client, reg_addr, *data);
if (dummy < 0)
return -1;
return 0;
}
static int bma150_smbus_read_byte_block(struct i2c_client *client,
unsigned char reg_addr, unsigned char *data, unsigned char len)
{
s32 dummy;
dummy = i2c_smbus_read_i2c_block_data(client, reg_addr, len, data);
if (dummy < 0)
return -1;
return 0;
}
static int bma150_set_mode(struct i2c_client *client, unsigned char Mode)
{
int comres = 0;
unsigned char data1, data2;
struct bma150_data *bma150 = i2c_get_clientdata(client);
if (client == NULL) {
comres = -1;
} else{
if (Mode < 4 && Mode != 1) {
comres = bma150_smbus_read_byte(client,
BMA150_WAKE_UP__REG, &data1);
data1 = BMA150_SET_BITSLICE(data1,
BMA150_WAKE_UP, Mode);
comres += bma150_smbus_read_byte(client,
BMA150_SLEEP__REG, &data2);
data2 = BMA150_SET_BITSLICE(data2,
BMA150_SLEEP, (Mode>>1));
comres += bma150_smbus_write_byte(client,
BMA150_WAKE_UP__REG, &data1);
comres += bma150_smbus_write_byte(client,
BMA150_SLEEP__REG, &data2);
mutex_lock(&bma150->mode_mutex);
bma150->mode = (unsigned char) Mode;
mutex_unlock(&bma150->mode_mutex);
} else{
comres = -1;
}
}
return comres;
}
static int bma150_set_range(struct i2c_client *client, unsigned char Range)
{
int comres = 0;
unsigned char data;
if (client == NULL) {
comres = -1;
} else{
if (Range < 3) {
comres = bma150_smbus_read_byte(client,
BMA150_RANGE__REG, &data);
data = BMA150_SET_BITSLICE(data, BMA150_RANGE, Range);
comres += bma150_smbus_write_byte(client,
BMA150_RANGE__REG, &data);
} else{
comres = -1;
}
}
return comres;
}
static int bma150_get_range(struct i2c_client *client, unsigned char *Range)
{
int comres = 0;
unsigned char data;
if (client == NULL) {
comres = -1;
} else{
comres = bma150_smbus_read_byte(client,
BMA150_RANGE__REG, &data);
*Range = BMA150_GET_BITSLICE(data, BMA150_RANGE);
}
return comres;
}
static int bma150_set_bandwidth(struct i2c_client *client, unsigned char BW)
{
int comres = 0;
unsigned char data;
if (client == NULL) {
comres = -1;
} else{
if (BW < 8) {
comres = bma150_smbus_read_byte(client,
BMA150_BANDWIDTH__REG, &data);
data = BMA150_SET_BITSLICE(data, BMA150_BANDWIDTH, BW);
comres += bma150_smbus_write_byte(client,
BMA150_BANDWIDTH__REG, &data);
} else{
comres = -1;
}
}
return comres;
}
static int bma150_get_bandwidth(struct i2c_client *client, unsigned char *BW)
{
int comres = 0;
unsigned char data;
if (client == NULL) {
comres = -1;
} else{
comres = bma150_smbus_read_byte(client,
BMA150_BANDWIDTH__REG, &data);
*BW = BMA150_GET_BITSLICE(data, BMA150_BANDWIDTH);
}
return comres;
}
static int bma150_read_accel_xyz(struct i2c_client *client,
struct bma150acc *acc)
{
int comres;
unsigned char data[6];
if (client == NULL) {
comres = -1;
} else{
comres = bma150_smbus_read_byte_block(client,
BMA150_ACC_X_LSB__REG, &data[0], 6);
acc->x = BMA150_GET_BITSLICE(data[0], BMA150_ACC_X_LSB) |
(BMA150_GET_BITSLICE(data[1], BMA150_ACC_X_MSB)<<
BMA150_ACC_X_LSB__LEN);
acc->x = acc->x << (sizeof(short)*8-(BMA150_ACC_X_LSB__LEN+
BMA150_ACC_X_MSB__LEN));
acc->x = acc->x >> (sizeof(short)*8-(BMA150_ACC_X_LSB__LEN+
BMA150_ACC_X_MSB__LEN));
acc->y = BMA150_GET_BITSLICE(data[2], BMA150_ACC_Y_LSB) |
(BMA150_GET_BITSLICE(data[3], BMA150_ACC_Y_MSB)<<
BMA150_ACC_Y_LSB__LEN);
acc->y = acc->y << (sizeof(short)*8-(BMA150_ACC_Y_LSB__LEN +
BMA150_ACC_Y_MSB__LEN));
acc->y = acc->y >> (sizeof(short)*8-(BMA150_ACC_Y_LSB__LEN +
BMA150_ACC_Y_MSB__LEN));
acc->z = BMA150_GET_BITSLICE(data[4], BMA150_ACC_Z_LSB);
acc->z |= (BMA150_GET_BITSLICE(data[5], BMA150_ACC_Z_MSB)<<
BMA150_ACC_Z_LSB__LEN);
acc->z = acc->z << (sizeof(short)*8-(BMA150_ACC_Z_LSB__LEN+
BMA150_ACC_Z_MSB__LEN));
acc->z = acc->z >> (sizeof(short)*8-(BMA150_ACC_Z_LSB__LEN+
BMA150_ACC_Z_MSB__LEN));
}
return comres;
}
static void bma150_work_func(struct work_struct *work)
{
struct bma150_data *bma150 = container_of((struct delayed_work *)work,
struct bma150_data, work);
static struct bma150acc acc;
s16 x,y,z;
unsigned long delay = msecs_to_jiffies(atomic_read(&bma150->delay));
struct bma023_platform_data *pdata = pdata = (bma150->bma150_client)->dev.platform_data;
bma150_read_accel_xyz(bma150->bma150_client, &acc);
if (pdata->swap_xyz) {
x = (pdata->orientation[0])*acc.x + (pdata->orientation[1])*acc.y + (pdata->orientation[2])*acc.z;
y = (pdata->orientation[3])*acc.x + (pdata->orientation[4])*acc.y + (pdata->orientation[5])*acc.z;
z = (pdata->orientation[6])*acc.x + (pdata->orientation[7])*acc.y + (pdata->orientation[8])*acc.z;
}
else {
x = acc.x;
y = acc.y;
z = acc.z;
}
input_report_abs(bma150->input, ABS_X, x);
input_report_abs(bma150->input, ABS_Y, y);
input_report_abs(bma150->input, ABS_Z, z);
input_sync(bma150->input);
mutex_lock(&bma150->value_mutex);
bma150->value = acc;
mutex_unlock(&bma150->value_mutex);
//printk("bma150_work_func acc.x=%d,acc.y=%d,acc.z=%d\n",acc.x,acc.y,acc.z);
schedule_delayed_work(&bma150->work, delay);
}
static ssize_t bma150_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
unsigned char data;
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
mutex_lock(&bma150->mode_mutex);
data = bma150->mode;
mutex_unlock(&bma150->mode_mutex);
return sprintf(buf, "%d\n", data);
}
static ssize_t bma150_mode_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned long data;
int error;
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
error = strict_strtoul(buf, 10, &data);
if (error)
return error;
if (bma150_set_mode(bma150->bma150_client, (unsigned char) data) < 0)
return -EINVAL;
return count;
}
static ssize_t bma150_range_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
unsigned char data;
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
if (bma150_get_range(bma150->bma150_client, &data) < 0)
return sprintf(buf, "Read error\n");
return sprintf(buf, "%d\n", data);
}
static ssize_t bma150_range_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned long data;
int error;
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
error = strict_strtoul(buf, 10, &data);
if (error)
return error;
if (bma150_set_range(bma150->bma150_client, (unsigned char) data) < 0)
return -EINVAL;
return count;
}
static ssize_t bma150_bandwidth_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
unsigned char data;
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
if (bma150_get_bandwidth(bma150->bma150_client, &data) < 0)
return sprintf(buf, "Read error\n");
return sprintf(buf, "%d\n", data);
}
static ssize_t bma150_bandwidth_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned long data;
int error;
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
error = strict_strtoul(buf, 10, &data);
if (error)
return error;
if (bma150_set_bandwidth(bma150->bma150_client,
(unsigned char) data) < 0)
return -EINVAL;
return count;
}
static ssize_t bma150_value_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct input_dev *input = to_input_dev(dev);
struct bma150_data *bma150 = input_get_drvdata(input);
struct bma150acc acc_value;
mutex_lock(&bma150->value_mutex);
acc_value = bma150->value;
mutex_unlock(&bma150->value_mutex);
return sprintf(buf, "%d %d %d\n", acc_value.x, acc_value.y,
acc_value.z);
}
static ssize_t bma150_delay_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
return sprintf(buf, "%d\n", atomic_read(&bma150->delay));
}
static ssize_t bma150_delay_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned long data;
int error;
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
error = strict_strtoul(buf, 10, &data);
if (error)
return error;
if (data > BMA150_MAX_DELAY)
data = BMA150_MAX_DELAY;
atomic_set(&bma150->delay, (unsigned int) data);
return count;
}
static ssize_t bma150_enable_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
return sprintf(buf, "%d\n", atomic_read(&bma150->enable));
}
static void bma150_set_enable(struct device *dev, int enable)
{
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
int pre_enable = atomic_read(&bma150->enable);
mutex_lock(&bma150->enable_mutex);
if (enable) {
if (pre_enable ==0) {
bma150_set_mode(bma150->bma150_client,
BMA150_MODE_NORMAL);
schedule_delayed_work(&bma150->work,
msecs_to_jiffies(atomic_read(&bma150->delay)));
atomic_set(&bma150->enable, 1);
}
} else {
if (pre_enable ==1) {
bma150_set_mode(bma150->bma150_client,
BMA150_MODE_SLEEP);
cancel_delayed_work_sync(&bma150->work);
atomic_set(&bma150->enable, 0);
}
}
mutex_unlock(&bma150->enable_mutex);
}
static ssize_t bma150_enable_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned long data;
int error;
error = strict_strtoul(buf, 10, &data);
if (error)
return error;
if ((data == 0)||(data==1)) {
bma150_set_enable(dev,data);
}
return count;
}
static DEVICE_ATTR(range, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
bma150_range_show, bma150_range_store);
static DEVICE_ATTR(bandwidth, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
bma150_bandwidth_show, bma150_bandwidth_store);
static DEVICE_ATTR(mode, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
bma150_mode_show, bma150_mode_store);
static DEVICE_ATTR(value, S_IRUGO|S_IWUSR|S_IWGRP,
bma150_value_show, NULL);
static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
bma150_delay_show, bma150_delay_store);
static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
bma150_enable_show, bma150_enable_store);
static struct attribute *bma150_attributes[] = {
&dev_attr_range.attr,
&dev_attr_bandwidth.attr,
&dev_attr_mode.attr,
&dev_attr_value.attr,
&dev_attr_delay.attr,
&dev_attr_enable.attr,
NULL
};
static struct attribute_group bma150_attribute_group = {
.attrs = bma150_attributes
};
static int bma150_input_init(struct bma150_data *bma150)
{
struct input_dev *dev;
int err;
dev = input_allocate_device();
if (!dev)
return -ENOMEM;
dev->name = "gsensor";//SENSOR_NAME;
dev->id.bustype = BUS_I2C;
input_set_capability(dev, EV_ABS, ABS_MISC);
input_set_abs_params(dev, ABS_X, ABSMIN_2G, ABSMAX_2G, 0, 0);
input_set_abs_params(dev, ABS_Y, ABSMIN_2G, ABSMAX_2G, 0, 0);
input_set_abs_params(dev, ABS_Z, ABSMIN_2G, ABSMAX_2G, 0, 0);
input_set_drvdata(dev, bma150);
err = input_register_device(dev);
if (err < 0) {
input_free_device(dev);
return err;
}
bma150->input = dev;
return 0;
}
static void bma150_input_delete(struct bma150_data *bma150)
{
struct input_dev *dev = bma150->input;
input_unregister_device(dev);
input_free_device(dev);
}
static int bma023_open(struct inode *inode, struct file *file)
{
return 0;//nonseekable_open(inode, file);
}
static int bma023_release(struct inode *inode, struct file *file)
{
return 0;
}
static struct file_operations bma023_fops = {
.owner = THIS_MODULE,
.open = bma023_open,
.release = bma023_release,
.unlocked_ioctl = bma023_ioctl,
};
static struct miscdevice bma023_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "mma8452_daemon",//"mma8452_daemon",
.fops = &bma023_fops,
};
static int bma023_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
void __user *argp = (void __user *)arg;
struct i2c_client *client = container_of(bma023_device.parent, struct i2c_client, dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);;
switch (cmd) {
case BMA_IOCTL_GETDATA:
mutex_lock(&bma150->value_mutex);
if(abs(sense_data.x-bma150->value.x)>10)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
sense_data.x=bma150->value.x;
if(abs(sense_data.y+(bma150->value.z))>10)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
sense_data.y=-(bma150->value.z);
if(abs(sense_data.z+(bma150->value.y))>10)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
sense_data.z=-(bma150->value.y);
//bma150->value = acc;
mutex_unlock(&bma150->value_mutex);
if ( copy_to_user(argp, &sense_data, sizeof(sense_data) ) ) {
printk("failed to copy sense data to user space.");
return -EFAULT;
}
break;
default:
break;
}
return 0;
}
static int bma150_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int err = 0;
int tempvalue;
struct bma150_data *data;
printk(KERN_INFO "bma150_probe \n");
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
printk(KERN_INFO "i2c_check_functionality error\n");
goto exit;
}
data = kzalloc(sizeof(struct bma150_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
tempvalue = 0;
tempvalue = i2c_smbus_read_word_data(client, BMA150_CHIP_ID_REG);
if ((tempvalue&0x00FF) == BMA150_CHIP_ID) {
printk(KERN_INFO "Bosch Sensortec Device detected!\n" \
"BMA150 registered I2C driver!\n");
} else{
printk(KERN_INFO "Bosch Sensortec Device not found" \
"i2c error %d \n", tempvalue);
err = -1;
goto kfree_exit;
}
i2c_set_clientdata(client, data);
data->bma150_client = client;
mutex_init(&data->value_mutex);
mutex_init(&data->mode_mutex);
mutex_init(&data->enable_mutex);
bma150_set_bandwidth(client, BMA150_BW_SET);
bma150_set_range(client, BMA150_RANGE_SET);
INIT_DELAYED_WORK(&data->work, bma150_work_func);
atomic_set(&data->delay, BMA150_MAX_DELAY);
atomic_set(&data->enable, 0);
err = bma150_input_init(data);
if (err < 0)
goto kfree_exit;
err = sysfs_create_group(&data->input->dev.kobj,
&bma150_attribute_group);
if (err < 0)
goto error_sysfs;
data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
data->early_suspend.suspend = bma150_early_suspend;
data->early_suspend.resume = bma150_late_resume;
register_early_suspend(&data->early_suspend);
bma023_device.parent = &client->dev;
misc_register(&bma023_device);
return 0;
error_sysfs:
bma150_input_delete(data);
kfree_exit:
kfree(data);
exit:
return err;
}
static int bma150_remove(struct i2c_client *client)
{
struct bma150_data *data = i2c_get_clientdata(client);
bma150_set_enable(&client->dev, 0);
unregister_early_suspend(&data->early_suspend);
sysfs_remove_group(&data->input->dev.kobj, &bma150_attribute_group);
bma150_input_delete(data);
kfree(data);
return 0;
}
static void bma150_early_suspend(struct early_suspend *h)
{
struct bma150_data *data =
container_of(h, struct bma150_data, early_suspend);
mutex_lock(&data->enable_mutex);
if (atomic_read(&data->enable)==1) {
bma150_set_mode(data->bma150_client, BMA150_MODE_SLEEP);
cancel_delayed_work_sync(&data->work);
}
mutex_unlock(&data->enable_mutex);
}
static void bma150_late_resume(struct early_suspend *h)
{
struct bma150_data *data =
container_of(h, struct bma150_data, early_suspend);
mutex_lock(&data->enable_mutex);
if (atomic_read(&data->enable)==1) {
bma150_set_mode(data->bma150_client, BMA150_MODE_NORMAL);
schedule_delayed_work(&data->work,
msecs_to_jiffies(atomic_read(&data->delay)));
}
mutex_unlock(&data->enable_mutex);
}
static const struct i2c_device_id bma150_id[] = {
{ SENSOR_NAME, 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, bma150_id);
static struct i2c_driver bma150_driver = {
.driver = {
.owner = THIS_MODULE,
.name = SENSOR_NAME,
},
.id_table = bma150_id,
.probe = bma150_probe,
.remove = bma150_remove,
};
static int __init BMA150_init(void)
{
return i2c_add_driver(&bma150_driver);
}
static void __exit BMA150_exit(void)
{
i2c_del_driver(&bma150_driver);
}
MODULE_AUTHOR("Lan Bin Yuan <lby@rock-chips.com>");
MODULE_DESCRIPTION("BMA150 driver");
MODULE_LICENSE("GPL");
module_init(BMA150_init);
module_exit(BMA150_exit);

View File

@@ -18,6 +18,9 @@ config INPUT_LPSENSOR_ISL29028
config INPUT_LPSENSOR_CM3602
tristate "l/p sensor input support"
config INPUT_LPSENSOR_AL3006
tristate "al3006 l/p sensor input support"
config INPUT_88PM860X_ONKEY
tristate "88PM860x ONKEY support"
depends on MFD_88PM860X

View File

@@ -49,4 +49,5 @@ obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
obj-$(CONFIG_INPUT_LPSENSOR_AL3006) += al3006.o

833
drivers/input/misc/al3006.c Normal file
View File

@@ -0,0 +1,833 @@
/* drivers/input/misc/al3006.c
*
* Copyright (C) 2010 ROCK-CHIPS, Inc.
* Author: eric <hc@rock-chips.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/circ_buf.h>
#include <linux/interrupt.h>
#include "al3006.h"
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/delay.h>
#include <linux/wait.h>
#define AL3006_DBG 0
#if AL3006_DBG
#define AL3006_DEBUG(x...) printk(x)
#else
#define AL3006_DEBUG(x...)
#endif
#define CONFIG_REG (0x00)
#define TIM_CTL_REG (0x01)
#define ALS_CTL_REG (0x02)
#define INT_STATUS_REG (0x03)
#define PS_CTL_REG (0x04)
#define PS_ALS_DATA_REG (0x05)
#define ALS_WINDOWS_REG (0x08)
//enable bit[ 0-1], in register CONFIG_REG
#define ONLY_ALS_EN (0x00)
#define ONLY_PROX_EN (0x01)
#define ALL_PROX_ALS_EN (0x02)
#define ALL_IDLE (0x03)
#define POWER_MODE_MASK (0x0C)
#define POWER_UP_MODE (0x00)
#define POWER_DOWN_MODE (0x08)
#define POWER_RESET_MODE (0x0C)
struct al3006_data {
struct input_dev *psensor_input_dev;
struct input_dev *lsensor_input_dev;
struct i2c_client *client;
struct delayed_work dwork; //for l/psensor
//struct delayed_work l_work; //for light sensor
struct mutex lock;
int enabled;
int irq;
};
static struct al3006_data al3006_struct_data;
#ifdef CONFIG_HAS_EARLYSUSPEND
static struct early_suspend al3006_early_suspend;
#endif
int g_lightlevel = 8;
static const int luxValues[8] = {
10, 160, 225, 320,
640, 1280, 2600, 4095
};
static int al3006_read_reg(struct i2c_client *client, char reg, char *value)
{
int ret = 0;
struct i2c_msg msg[2];
struct i2c_adapter *adap = client->adapter;
msg[0].addr = client->addr;
msg[0].flags = client->flags;
msg[0].len = 1;
msg[0].buf = (char *)&reg;
msg[0].scl_rate = 400 * 1000;
msg[1].addr = client->addr;
msg[1].flags = client->flags | I2C_M_RD;
msg[1].len = 1;
msg[1].buf = (char *)value;
msg[1].scl_rate = 400 * 1000;
if ((ret = i2c_transfer(adap, (struct i2c_msg *)&msg, 2)) < 2) {
AL3006_DEBUG("%s: read al3006 register %#x failure\n", __FUNCTION__, reg);
return -EIO;
}
return 1;
}
static int al3006_write_reg(struct i2c_client *client, char reg, char value)
{
int ret = 0;
char buf[2];
struct i2c_msg msg;
struct i2c_adapter *adap = client->adapter;
buf[0] = reg;
buf[1] = value;
msg.addr = client->addr;
msg.flags = client->flags;
msg.len = 2;
msg.buf = (char *)&buf;
msg.scl_rate = 400 * 1000;
if ((ret = i2c_transfer(adap, (struct i2c_msg *)&msg, 1)) < 1) {
AL3006_DEBUG("%s: read al3006 register %#x failure\n", __FUNCTION__, reg);
return -EIO;
}
return 1;
}
static void al3006_change_ps_threshold(struct i2c_client *client)
{
struct al3006_data *al3006 = i2c_get_clientdata(client);
char reg, value;
AL3006_DEBUG("%s:\n", __FUNCTION__);
mutex_lock(&al3006->lock);
reg = PS_ALS_DATA_REG;
al3006_read_reg(client, reg, &value);
mutex_unlock(&al3006->lock);
value >>= 7; //bit7 is ps data ; bit7 = 1, object is detected
printk("%s: psensor's data is %#x\n", __FUNCTION__, value);
input_report_abs(al3006->psensor_input_dev, ABS_DISTANCE, value?0:1);
input_sync(al3006->psensor_input_dev);
}
static void al3006_change_ls_threshold(struct i2c_client *client)
{
struct al3006_data *al3006 = i2c_get_clientdata(client);
char reg, value;
AL3006_DEBUG("%s:\n", __FUNCTION__);
mutex_lock(&al3006->lock);
reg = PS_ALS_DATA_REG;
al3006_read_reg(client, reg, &value);
mutex_unlock(&al3006->lock);
value &= 0x3F; // bit0-5 is ls data;
printk("%s: lightsensor's level is %#x\n", __FUNCTION__, value);
if(value > 8) value = 8;
input_report_abs(al3006->lsensor_input_dev, ABS_MISC, value);
input_sync(al3006->lsensor_input_dev);
}
static void al3006_work_handler(struct work_struct *work)
{
struct al3006_data *al3006 = (struct al3006_data *)container_of(work, struct al3006_data, dwork.work);
char reg, value;
mutex_lock(&al3006->lock);
reg = INT_STATUS_REG;
al3006_read_reg(al3006->client, reg, &value);
mutex_unlock(&al3006->lock);
AL3006_DEBUG("%s: INT_STATUS_REG is %#x\n", __FUNCTION__, value);
value &= 0x03;
if(value == 0x02) { //ps int
al3006_change_ps_threshold(al3006->client);
}
else if(value == 0x01) { //ls int
al3006_change_ls_threshold(al3006->client);
}
else if(value == 0x03) { //ps and ls int
al3006_change_ps_threshold(al3006->client);
al3006_change_ls_threshold(al3006->client);
}
//enable_irq(al3006->irq);
}
static void al3006_reschedule_work(struct al3006_data *data,
unsigned long delay)
{
unsigned long flags;
spin_lock_irqsave(&data->lock, flags);
/*
* If work is already scheduled then subsequent schedules will not
* change the scheduled time that's why we have to cancel it first.
*/
__cancel_delayed_work(&data->dwork);
schedule_delayed_work(&data->dwork, delay);
spin_unlock_irqrestore(&data->lock, flags);
}
static irqreturn_t al3006_irq_handler(int irq, void *data)
{
struct al3006_data *al3006 = (struct al3006_data *)data;
AL3006_DEBUG("%s\n", __FUNCTION__);
//input_report_abs(al3006->psensor_input_dev, ABS_DISTANCE, 0);
//input_sync(al3006->psensor_input_dev);
//disable_irq_nosync(al3006->irq);
al3006_reschedule_work(al3006, 0);//msecs_to_jiffies(420)
return IRQ_HANDLED;
}
static int al3006_psensor_enable(struct i2c_client *client)
{
char reg, value;
int ret;
struct al3006_data *al3006 = (struct al3006_data *)i2c_get_clientdata(client);
AL3006_DEBUG("%s:\n", __FUNCTION__);
mutex_lock(&al3006->lock);
reg = CONFIG_REG;
ret = al3006_read_reg(client, reg, &value);
if( (value & 0x03) == ONLY_ALS_EN ){
value &= ~0x03;
value |= ALL_PROX_ALS_EN;
ret = al3006_write_reg(client, reg, value);
}
else if( (value & 0x03) == ALL_IDLE ){
value &= ~0x03;
value |= ONLY_PROX_EN;
ret = al3006_write_reg(client, reg, value);
}
#ifdef AL3006_DBG
ret = al3006_read_reg(client, reg, &value);
AL3006_DEBUG("%s: configure reg value %#x ...\n", __FUNCTION__, value);
#endif
reg = PS_ALS_DATA_REG;
al3006_read_reg(client, reg, &value);
value >>= 7; //bit7 is ps data ; bit7 = 1, object is detected
printk("%s: psensor's data is %#x\n", __FUNCTION__, value);
input_report_abs(al3006->psensor_input_dev, ABS_DISTANCE, value?0:1);
input_sync(al3006->psensor_input_dev);
mutex_unlock(&al3006->lock);
//enable_irq(al3006->irq);
return ret;
}
static int al3006_psensor_disable(struct i2c_client *client)
{
char ret, reg, value;
struct al3006_data *al3006 = (struct al3006_data *)i2c_get_clientdata(client);
mutex_lock(&al3006->lock);
reg = CONFIG_REG;
ret = al3006_read_reg(client, reg, &value);
if( (value & 0x03) == ONLY_PROX_EN ){
value &= ~0x03;
value |= ALL_IDLE;
ret = al3006_write_reg(client, reg, value);
}
else if( (value & 0x03) == ALL_PROX_ALS_EN ){
value &= ~0x03;
value |= ONLY_ALS_EN;
ret = al3006_write_reg(client, reg, value);
}
#ifdef AL3006_DBG
ret = al3006_read_reg(client, reg, &value);
AL3006_DEBUG("%s: configure reg value %#x ...\n", __FUNCTION__, value);
#endif
mutex_unlock(&al3006->lock);
//disable_irq(al3006->irq);
//cancel_delayed_work_sync(&al3006->dwork);
//enable_irq(al3006->irq);
return ret;
}
static int misc_ps_opened = 0;
static int al3006_psensor_open(struct inode *inode, struct file *file)
{
// struct i2c_client *client =
// container_of (al3006_psensor_misc.parent, struct i2c_client, dev);
printk("%s\n", __func__);
if (misc_ps_opened)
return -EBUSY;
misc_ps_opened = 1;
return 0;
}
static int al3006_psensor_release(struct inode *inode, struct file *file)
{
// struct i2c_client *client =
// container_of (al3006_psensor_misc.parent, struct i2c_client, dev);
printk("%s\n", __func__);
misc_ps_opened = 0;
return 0;
}
static long al3006_psensor_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
char reg, val, enabled;
struct al3006_data *al3006 = &al3006_struct_data;
struct i2c_client *client = al3006->client;
printk("%s cmd %d\n", __func__, _IOC_NR(cmd));
switch (cmd) {
case PSENSOR_IOCTL_ENABLE:
if (get_user(val, (unsigned long __user *)arg))
return -EFAULT;
if (val)
return al3006_psensor_enable(client);
else
return al3006_psensor_disable(client);
break;
case PSENSOR_IOCTL_GET_ENABLED:
mutex_lock(&al3006->lock);
reg = CONFIG_REG;
al3006_read_reg(client, reg, &val);
mutex_unlock(&al3006->lock);
val &= 0x03;
if(val == ONLY_PROX_EN || val == ALL_PROX_ALS_EN)
enabled = 1;
else
enabled = 0;
return put_user(enabled, (unsigned long __user *)arg);
break;
default:
pr_err("%s: invalid cmd %d\n", __func__, _IOC_NR(cmd));
return -EINVAL;
}
}
static struct file_operations al3006_psensor_fops = {
.owner = THIS_MODULE,
.open = al3006_psensor_open,
.release = al3006_psensor_release,
.unlocked_ioctl = al3006_psensor_ioctl
};
static struct miscdevice al3006_psensor_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "psensor",
.fops = &al3006_psensor_fops
};
static int register_psensor_device(struct i2c_client *client, struct al3006_data *data)
{
struct input_dev *input_dev = data->psensor_input_dev;
int rc;
AL3006_DEBUG("%s: allocating input device psensor\n", __func__);
input_dev = input_allocate_device();
if (!input_dev) {
dev_err(&client->dev,"%s: could not allocate input device for psensor\n", __FUNCTION__);
rc = -ENOMEM;
goto done;
}
data->psensor_input_dev = input_dev;
input_set_drvdata(input_dev, data);
input_set_drvdata(input_dev, data);
input_dev->name = "proximity";
set_bit(EV_ABS, input_dev->evbit);
input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);
AL3006_DEBUG("%s: registering input device psensor\n", __FUNCTION__);
rc = input_register_device(input_dev);
if (rc < 0) {
pr_err("%s: could not register input device for psensor\n", __FUNCTION__);
goto done;
}
AL3006_DEBUG("%s: registering misc device for psensor\n", __FUNCTION__);
rc = misc_register(&al3006_psensor_misc);
if (rc < 0) {
pr_err("%s: could not register misc device psensor\n", __FUNCTION__);
goto err_unregister_input_device;
}
al3006_psensor_misc.parent = &client->dev;
//INIT_DELAYED_WORK(&data->p_work, al3006_psensor_work_handler);
return 0;
err_unregister_input_device:
input_unregister_device(input_dev);
done:
return rc;
}
static void unregister_psensor_device(struct i2c_client *client, struct al3006_data *data)
{
misc_deregister(&al3006_psensor_misc);
input_unregister_device(data->psensor_input_dev);
}
#define LSENSOR_POLL_PROMESHUTOK 1000
static int al3006_lsensor_enable(struct i2c_client *client)
{
char reg, value;
int ret;
struct al3006_data *al3006 = (struct al3006_data *)i2c_get_clientdata(client);
mutex_lock(&al3006->lock);
reg = CONFIG_REG;
ret = al3006_read_reg(client, reg, &value);
if( (value & 0x03) == ONLY_PROX_EN ){
value &= ~0x03;
value |= ALL_PROX_ALS_EN;
ret = al3006_write_reg(client, reg, value);
}
else if( (value & 0x03) == ALL_IDLE ){
value &= ~0x03;
value |= ONLY_ALS_EN;
ret = al3006_write_reg(client, reg, value);
}
#ifdef AL3006_DBG
ret = al3006_read_reg(client, reg, &value);
AL3006_DEBUG("%s: configure reg value %#x ...\n", __FUNCTION__, value);
#endif
mutex_unlock(&al3006->lock);
//schedule_delayed_work(&(al3006->l_work), msecs_to_jiffies(LSENSOR_POLL_PROMESHUTOK));
return ret;
}
static int al3006_lsensor_disable(struct i2c_client *client)
{
char ret, reg, value;
struct al3006_data *al3006 = (struct al3006_data *)i2c_get_clientdata(client);
//cancel_delayed_work_sync(&(al3006->l_work));
mutex_lock(&al3006->lock);
reg = CONFIG_REG;
ret = al3006_read_reg(client, reg, &value);
if( (value & 0x03) == ONLY_ALS_EN ){
value &= ~0x03;
value |= ALL_IDLE;
ret = al3006_write_reg(client, reg, value);
}
else if( (value & 0x03) == ALL_PROX_ALS_EN ){
value &= ~0x03;
value |= ONLY_PROX_EN;
ret = al3006_write_reg(client, reg, value);
}
#ifdef AL3006_DBG
ret = al3006_read_reg(client, reg, &value);
AL3006_DEBUG("%s: configure reg value %#x ...\n", __FUNCTION__, value);
#endif
mutex_unlock(&al3006->lock);
return ret;
}
static int luxValue_to_level(int value)
{
int i;
if (value >= luxValues[7])
return 7;
if (value <= luxValues[0])
return 0;
for (i=0;i<7;i++)
if (value>=luxValues[i] && value<luxValues[i+1])
return i;
return -1;
}
static int misc_ls_opened = 0;
static int al3006_lsensor_open(struct inode *inode, struct file *file)
{
// struct i2c_client *client =
// container_of (al3006_lsensor_misc.parent, struct i2c_client, dev);
printk("%s\n", __func__);
if (misc_ls_opened)
return -EBUSY;
misc_ls_opened = 1;
return 0;
}
static int al3006_lsensor_release(struct inode *inode, struct file *file)
{
// struct i2c_client *client =
// container_of (al3006_lsensor_misc.parent, struct i2c_client, dev);
printk("%s\n", __func__);
misc_ls_opened = 0;
return 0;
}
static long al3006_lsensor_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
char reg, val, enabled;
struct al3006_data *al3006 = &al3006_struct_data;
struct i2c_client *client = al3006->client;
printk("%s cmd %d\n", __FUNCTION__, _IOC_NR(cmd));
switch (cmd) {
case LIGHTSENSOR_IOCTL_ENABLE:
if (get_user(val, (unsigned long __user *)arg))
return -EFAULT;
if (val)
return al3006_lsensor_enable(client);
else
return al3006_lsensor_disable(client);
break;
case LIGHTSENSOR_IOCTL_GET_ENABLED:
mutex_lock(&al3006->lock);
reg =CONFIG_REG;
al3006_read_reg(client, reg, &val);
mutex_unlock(&al3006->lock);
val &= 0x03;
if(val == ONLY_ALS_EN || val == ALL_PROX_ALS_EN)
enabled = 1;
else
enabled = 0;
return put_user(enabled, (unsigned long __user *)arg);
break;
default:
pr_err("%s: invalid cmd %d\n", __func__, _IOC_NR(cmd));
return -EINVAL;
}
}
static struct file_operations al3006_lsensor_fops = {
.owner = THIS_MODULE,
.open = al3006_lsensor_open,
.release = al3006_lsensor_release,
.unlocked_ioctl = al3006_lsensor_ioctl
};
static struct miscdevice al3006_lsensor_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "lightsensor",
.fops = &al3006_lsensor_fops
};
static int register_lsensor_device(struct i2c_client *client, struct al3006_data *data)
{
struct input_dev *input_dev = data->lsensor_input_dev;
int rc;
AL3006_DEBUG("%s: allocating input device lsensor\n", __func__);
input_dev = input_allocate_device();
if (!input_dev) {
dev_err(&client->dev,"%s: could not allocate input device for lsensor\n", __FUNCTION__);
rc = -ENOMEM;
goto done;
}
data->lsensor_input_dev = input_dev;
input_set_drvdata(input_dev, data);
input_set_drvdata(input_dev, data);
input_dev->name = "lightsensor-level";
set_bit(EV_ABS, input_dev->evbit);
input_set_abs_params(input_dev, ABS_MISC, 0, 8, 0, 0);
AL3006_DEBUG("%s: registering input device al3006 lsensor\n", __FUNCTION__);
rc = input_register_device(input_dev);
if (rc < 0) {
pr_err("%s: could not register input device for lsensor\n", __FUNCTION__);
goto done;
}
AL3006_DEBUG("%s: registering misc device for al3006's lsensor\n", __FUNCTION__);
rc = misc_register(&al3006_lsensor_misc);
if (rc < 0) {
pr_err("%s: could not register misc device lsensor\n", __FUNCTION__);
goto err_unregister_input_device;
}
al3006_lsensor_misc.parent = &client->dev;
//INIT_DELAYED_WORK(&data->l_work, al3006_lsensor_work_handler);
return 0;
err_unregister_input_device:
input_unregister_device(input_dev);
done:
return rc;
}
static void unregister_lsensor_device(struct i2c_client *client, struct al3006_data *al3006)
{
misc_deregister(&al3006_lsensor_misc);
input_unregister_device(al3006->lsensor_input_dev);
}
static int al3006_config(struct i2c_client *client)
{
char value;
//struct al3006_data *al3006 = (struct al3006_data *)i2c_get_clientdata(client);
AL3006_DEBUG("%s: init al3006 all register\n", __FUNCTION__);
/***********************config**************************/
value = 0x41;//The ADC effective resolution = 9; Low lux threshold level = 1;
//value = 0x69; //The ADC effective resolution = 17; Low lux threshold level = 9;
al3006_write_reg(client, ALS_CTL_REG, value);
//value = 0x04;//0x01-0x0f; 17%->93.5% if value = 0x04,then Compensate Loss 52%
value = 0x02;//0x01-0x0f; 17%->93.5% if value = 0x02,then Compensate Loss 31%
al3006_write_reg(client, ALS_WINDOWS_REG, value);
return 0;
}
void disable_al3006_device(struct i2c_client *client)
{
char value;
struct al3006_data *al3006 = (struct al3006_data *)i2c_get_clientdata(client);
#if 0
mutex_lock(&al3006->lock);
al3006_read_reg(client, CONFIG_REG, &value);
value &= ~POWER_MODE_MASK;
value |= POWER_DOWN_MODE;
al3006_write_reg(client, CONFIG_REG, value);
mutex_unlock(&al3006->lock);
#endif
mutex_lock(&al3006->lock);
al3006_write_reg(client, CONFIG_REG, 0x0B);
al3006_read_reg(client, CONFIG_REG, &value);
mutex_unlock(&al3006->lock);
AL3006_DEBUG("%s: value = 0x%x\n", __FUNCTION__,value);
}
void enable_al3006_device(struct i2c_client *client)
{
char value;
struct al3006_data *al3006 = (struct al3006_data *)i2c_get_clientdata(client);
mutex_lock(&al3006->lock);
al3006_read_reg(client, CONFIG_REG, &value);
value &= ~POWER_MODE_MASK;
value |= POWER_UP_MODE;
al3006_write_reg(client, CONFIG_REG, value);
al3006_read_reg(client, CONFIG_REG, &value);
mutex_unlock(&al3006->lock);
AL3006_DEBUG("%s: value = 0x%x\n", __FUNCTION__,value);
#if 0
mutex_lock(&al3006->lock);
al3006_write_reg(client, CONFIG_REG, 0x03);
mutex_unlock(&al3006->lock);
#endif
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void al3006_suspend(struct early_suspend *h)
{
struct i2c_client *client = container_of(al3006_psensor_misc.parent, struct i2c_client, dev);
struct al3006_data *al3006 = (struct al3006_data *)i2c_get_clientdata(client);
printk("al3006 early suspend ========================= \n");
if (misc_ls_opened)
al3006_lsensor_disable(client);
if (misc_ps_opened)
//al3006_psensor_disable(client);
enable_irq_wake(al3006->irq);
else
disable_al3006_device(client);
//disable_al3006_device(client);
}
static void al3006_resume(struct early_suspend *h)
{
struct i2c_client *client = container_of(al3006_psensor_misc.parent, struct i2c_client, dev);
struct al3006_data *al3006 = (struct al3006_data *)i2c_get_clientdata(client);
printk("al3006 early resume ======================== \n");
if (misc_ps_opened)
//al3006_psensor_enable(client);
disable_irq_wake(al3006->irq);
if (misc_ls_opened)
al3006_lsensor_enable(client);
enable_al3006_device(client);
}
#else
#define al3006_suspend NULL
#define al3006_resume NULL
#endif
static int al3006_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct al3006_data *al3006 = &al3006_struct_data;
int rc = -EIO;
char value = 0;
printk("\n%s: al3006 i2c client probe\n\n", __FUNCTION__);
al3006_read_reg(client, CONFIG_REG, &value);
printk("\n%s: al3006's CONFIG_REG value = 0x%x\n", __FUNCTION__, value);
al3006->client = client;
i2c_set_clientdata(client, al3006);
mutex_init(&al3006->lock);
rc = register_psensor_device(client, al3006);
if (rc) {
dev_err(&client->dev, "failed to register_psensor_device\n");
goto done;
}
rc = register_lsensor_device(client, al3006);
if (rc) {
dev_err(&client->dev, "failed to register_lsensor_device\n");
goto unregister_device1;
}
rc = al3006_config(client);
if (rc) {
dev_err(&client->dev, "failed to al3006_config\n");
goto unregister_device2;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
al3006_early_suspend.suspend = al3006_suspend;
al3006_early_suspend.resume = al3006_resume;
al3006_early_suspend.level = 0x02;
register_early_suspend(&al3006_early_suspend);
#endif
INIT_DELAYED_WORK(&al3006->dwork, al3006_work_handler);
rc = gpio_request(client->irq, "al3006 irq");
if (rc) {
pr_err("%s: request gpio %d for al3006 irq failed \n", __FUNCTION__, client->irq);
goto unregister_device2;
}
rc = gpio_direction_input(client->irq);
if (rc) {
pr_err("%s: failed set gpio input\n", __FUNCTION__);
}
gpio_pull_updown(client->irq, GPIOPullUp);
al3006->irq = gpio_to_irq(client->irq);
mdelay(1);
rc = request_irq(al3006->irq, al3006_irq_handler,
IRQ_TYPE_EDGE_FALLING, client->name, (void *)al3006);//IRQ_TYPE_LEVEL_LOW
if (rc < 0) {
dev_err(&client->dev,"request_irq failed for gpio %d (%d)\n", client->irq, rc);
goto err_free_gpio;
}
//al3006_psensor_enable(client);
//al3006_lsensor_enable(client);
return 0;
err_free_gpio:
gpio_free(client->irq);
unregister_device2:
unregister_lsensor_device(client, &al3006_struct_data);
unregister_device1:
unregister_psensor_device(client, &al3006_struct_data);
done:
return rc;
}
static int al3006_remove(struct i2c_client *client)
{
struct al3006_data *data = i2c_get_clientdata(client);
unregister_psensor_device(client, data);
unregister_lsensor_device(client, data);
#ifdef CONFIG_HAS_EARLYSUSPEND
unregister_early_suspend(&al3006_early_suspend);
#endif
return 0;
}
static const struct i2c_device_id al3006_id[] = {
{"al3006", 0},
{ }
};
static struct i2c_driver al3006_driver = {
.driver = {
.name = "al3006",
},
.probe = al3006_probe,
.remove = al3006_remove,
.id_table = al3006_id,
};
static int __init al3006_init(void)
{
return i2c_add_driver(&al3006_driver);
}
static void __exit al3006_exit(void)
{
return i2c_del_driver(&al3006_driver);
}
module_init(al3006_init);
module_exit(al3006_exit);

View File

@@ -0,0 +1,33 @@
/* include/linux/isl29028.h
*
* Copyright (C) 2009 Google, Inc.
* Author: Iliyan Malchev <malchev@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __LINUX_AL3006_H
#define __LINUX_AL3006_H
#include <linux/types.h>
#include <linux/ioctl.h>
#define PSENSOR_IOCTL_MAGIC 'c'
#define PSENSOR_IOCTL_GET_ENABLED \
_IOR(PSENSOR_IOCTL_MAGIC, 1, int *)
#define PSENSOR_IOCTL_ENABLE \
_IOW(PSENSOR_IOCTL_MAGIC, 2, int *)
#define LIGHTSENSOR_IOCTL_MAGIC 'l'
#define LIGHTSENSOR_IOCTL_GET_ENABLED _IOR(LIGHTSENSOR_IOCTL_MAGIC, 1, int *)
#define LIGHTSENSOR_IOCTL_ENABLE _IOW(LIGHTSENSOR_IOCTL_MAGIC, 2, int *)
#endif

View File

@@ -27,6 +27,7 @@
#include <linux/circ_buf.h>
#include <linux/interrupt.h>
#include "isl29028.h"
#include <linux/slab.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>

View File

@@ -115,6 +115,13 @@ config TOUCHSCREEN_ILI2102_IIC
code includes that in its table of IIC devices.
If unsure, say N (but it's safe to say "Y").
config TOUCHSCREEN_GT8XX
tristate "Goodix touch screen gt8xx support for rk29"
help
Say Y here if you have a touchscreen interface using the
goodix gt8xx , and your board-specific initialization
code includes that in its table of IIC devices.
If unsure, say N (but it's safe to say "Y").
config RK28_I2C_TS_NTP070
tristate "NTP070 based touchscreens: NTP070 Interface"
@@ -954,6 +961,10 @@ config TOUCHSCREEN_GT818_IIC
tristate "GT818_IIC based touchscreens"
depends on I2C2_RK29
config TOUCHSCREEN_PIXCIR
tristate "PIXCIR_IIC based touchscreens"
depends on I2C2_RK29
config D70_L3188A
tristate "D70-L3188A based touchscreens"
depends on I2C2_RK29

View File

@@ -78,7 +78,9 @@ obj-$(CONFIG_TOUCHSCREEN_GT801_IIC) += gt801_ts.o
obj-$(CONFIG_TOUCHSCREEN_GT818_IIC) += gt818_ts.o
obj-$(CONFIG_TOUCHSCREEN_ILI2102_IIC) += ili2102_ts.o
obj-$(CONFIG_D70_L3188A) += goodix_touch.o
obj-$(CONFIG_TOUCHSCREEN_GT8XX) += rk29_i2c_goodix.o
obj-$(CONFIG_TOUCHSCREEN_FT5406) += ft5406_ts.o
obj-$(CONFIG_TOUCHSCREEN_GT819) += gt819.o
obj-$(CONFIG_TOUCHSCREEN_NAS) += nas_ts.o
obj-$(CONFIG_LAIBAO_TS) += ft5x0x_i2c_ts.o
obj-$(CONFIG_TOUCHSCREEN_PIXCIR) += pixcir_i2c_ts.o

View File

@@ -376,7 +376,6 @@ static void ProcessReport(unsigned char *buf, int buflen)
input_mt_slot(input_dev, i);
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, true);
input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, PointBuf[i].Status);
input_report_abs(input_dev, ABS_MT_PRESSURE, 100);
input_report_abs(input_dev, ABS_MT_POSITION_X, PointBuf[i].X);
input_report_abs(input_dev, ABS_MT_POSITION_Y, PointBuf[i].Y);
@@ -421,7 +420,6 @@ static struct input_dev * allocate_Input_Dev(void)
input_set_abs_params(pInputDev, ABS_MT_POSITION_X, 0, CONFIG_EETI_EGALAX_MAX_X, 0, 0);
input_set_abs_params(pInputDev, ABS_MT_POSITION_Y, 0, CONFIG_EETI_EGALAX_MAX_Y, 0, 0);
input_set_abs_params(pInputDev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
input_set_abs_params(pInputDev, ABS_MT_PRESSURE, 0, 255, 0, 0);
ret = input_register_device(pInputDev);
if(ret)
@@ -503,7 +501,6 @@ static void egalax_i2c_wq(struct work_struct *work)
input_mt_slot(input_dev, i);
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, true);
input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 0);
input_report_abs(input_dev, ABS_MT_PRESSURE, 100);
input_report_abs(input_dev, ABS_MT_POSITION_X, PointBuf[i].X);
input_report_abs(input_dev, ABS_MT_POSITION_Y, PointBuf[i].Y);
PointBuf[i].Status = 0;

View File

@@ -40,6 +40,7 @@
#include <linux/string.h>
#include <linux/completion.h>
#include <asm/uaccess.h>
#include <linux/input/mt.h>
#include "gt818_ts.h"
@@ -76,6 +77,9 @@ static void goodix_ts_late_resume(struct early_suspend *h);
#define MAX_KEY_NUM (sizeof(gt818_key_array)/sizeof(gt818_key_array[0]))
#endif
unsigned int last_x[MAX_FINGER_NUM + 1]= {0};
unsigned int last_y[MAX_FINGER_NUM + 1]= {0};
/*Function as i2c_master_send */
static int i2c_read_bytes(struct i2c_client *client, u8 *buf, int len)
@@ -303,19 +307,23 @@ static void goodix_ts_work_func(struct work_struct *work)
for(position = 1; position < MAX_FINGER_NUM + 1; position++)
{
//printk("%s:positon:%d\n", __func__, position);
if((finger_current[position] == 0) && (finger_last[position] != 0))
{
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, 0);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, 0);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
input_mt_sync(ts->input_dev);
//printk("<<<<<<<<<<<<<<<<<<<%s:positon:%d (%d,%d)\n", __func__, position,last_x,last_y);
//printk("<<<%d , %d ",finger_current[position],finger_last[position]);
//input_mt_slot(ts->input_dev, position);
//input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
//input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
//input_report_abs(ts->input_dev, ABS_MT_POSITION_X, last_x[position]);
//input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, last_y[position]);
//input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100);
//input_mt_sync(ts->input_dev);
input_mt_slot(ts->input_dev, position);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
syn_flag = 1;
}
else if(finger_current[position])
{
x = (*(coor_point+3*(position-1)))*SCREEN_MAX_WIDTH/(TOUCH_MAX_WIDTH);
y = (*(coor_point+3*(position-1)+1))*SCREEN_MAX_HEIGHT/(TOUCH_MAX_HEIGHT);
pressure = (*(coor_point+3*(position-1)+2));
@@ -326,15 +334,25 @@ static void goodix_ts_work_func(struct work_struct *work)
if(y < SCREEN_MAX_HEIGHT){
// y = SCREEN_MAX_HEIGHT-y;
}
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, position - 1);
//printk(">>>>>>>>>>>>>>>>>%s:positon:%d (%d,%d)\n", __func__, position,x,y);
input_mt_slot(ts->input_dev, position);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);
input_report_abs(ts->input_dev, ABS_MT_PRESSURE, pressure);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, pressure);
input_mt_sync(ts->input_dev);
last_x[position] = x;
last_y[position] = y;
//input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, pressure);
//input_mt_sync(ts->input_dev);
syn_flag = 1;
}
}
}
input_sync(ts->input_dev);
#ifdef HAVE_TOUCH_KEY
@@ -488,7 +506,7 @@ static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id
struct gt818_ts_data *ts;
struct gt818_platform_data *pdata;
dev_dbg(&client->dev,"Install touch driver.\n");
dev_info(&client->dev,"Install touch driver.\n");
printk("gt818: Install touch driver.\n");
//Check I2C function
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
@@ -576,10 +594,10 @@ static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id
goto err_input_dev_alloc_failed;
}
ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ;
ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
ts->input_dev->absbit[0] = BIT_MASK(ABS_MT_POSITION_X) | BIT_MASK(ABS_MT_POSITION_Y) |
BIT_MASK(ABS_MT_TOUCH_MAJOR) | BIT_MASK(ABS_MT_WIDTH_MAJOR); // for android
//ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ;
//ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
//ts->input_dev->absbit[0] = BIT_MASK(ABS_MT_POSITION_X) | BIT_MASK(ABS_MT_POSITION_Y) |
// BIT_MASK(ABS_MT_TOUCH_MAJOR) | BIT_MASK(ABS_MT_WIDTH_MAJOR); // for android
#ifdef HAVE_TOUCH_KEY
@@ -600,13 +618,16 @@ static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id
ts->input_dev->id.product = 0xBEEF;
ts->input_dev->id.version = 10427; //screen firmware version
__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
__set_bit(EV_ABS, ts->input_dev->evbit);
#ifdef GOODIX_MULTI_TOUCH
input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
input_mt_init_slots(ts->input_dev, MAX_FINGER_NUM);
//input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_WIDTH, 0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_HEIGHT, 0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, MAX_FINGER_NUM, 0, 0);
//input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, MAX_FINGER_NUM, 0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
#else
input_set_abs_params(ts->input_dev, ABS_X, 0, SCREEN_MAX_HEIGHT, 0, 0);
input_set_abs_params(ts->input_dev, ABS_Y, 0, SCREEN_MAX_WIDTH, 0, 0);
@@ -619,7 +640,7 @@ static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id
goto err_input_register_device_failed;
}
ts->bad_data = 0;
// finger_list.length = 0;
// 16finger_list.length = 0;
client->irq = gpio_to_irq(pdata->gpio_pendown); //If not defined in client
if (client->irq)
@@ -834,6 +855,6 @@ late_initcall(goodix_ts_init);
module_exit(goodix_ts_exit);
MODULE_DESCRIPTION("Goodix Touchscreen Driver");
MODULE_AUTHOR("hhb@rock-chips.com")
MODULE_AUTHOR("hhb@rock-chips.com");
MODULE_LICENSE("GPL");

View File

@@ -298,11 +298,13 @@ static int verify_coord(struct ili2102_ts_data *ts,unsigned int *x,unsigned int
{
//DBG("%s:(%d/%d)\n",__FUNCTION__,*x, *y);
#ifndef CONFIG_MACH_RK29_TD8801_V2
if((*x< ts->x_min) || (*x > ts->x_max))
return -1;
if((*y< ts->y_min) || (*y > ts->y_max))
return -1;
#endif
/*android do not support min and max value*/
if(*x == ts->x_min)
@@ -398,7 +400,10 @@ static void ili2102_ts_work_func(struct work_struct *work)
x = g_x[i];
y = g_y[i];
}
#ifdef CONFIG_MACH_RK29_TD8801_V2
if( y >=80 ) y-=80;
if( x >= 50 ) x-=50;
#endif
g_x[i] = x;
g_y[i] = y;
input_event(ts->input_dev, EV_ABS, ABS_MT_TRACKING_ID, i);

View File

@@ -0,0 +1,920 @@
/*
* Driver for Pixcir I2C touchscreen controllers.
*
* Copyright (C) 2010-2011 Pixcir, Inc.
*
* pixcir_i2c_ts.c V3.0 from v3.0 support TangoC solution and remove the previous soltutions
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/earlysuspend.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <mach/iomux.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/proc_fs.h>
#include "pixcir_i2c_ts.h"
#define PIXCIR_DEBUG 0
#if PIXCIR_DEBUG
#define pixcir_dbg(msg...) printk(msg);
#else
#define pixcir_dbg(msg...)
#endif
static int ts_dbg_enable = 0;
#define DBG(msg...) \
({if(ts_dbg_enable == 1) printk(msg);})
/*********************************Bee-0928-TOP****************************************/
#define SLAVE_ADDR 0x5c
#ifndef I2C_MAJOR
#define I2C_MAJOR 125
#endif
#define I2C_MINORS 256
#define CALIBRATION_FLAG 1
static unsigned char status_reg = 0;
static struct workqueue_struct *pixcir_wq;
static struct pixcir_i2c_ts_data *this_data;
struct point_data{
unsigned char brn; //broken line number
unsigned char brn_pre;
unsigned char id; //finger ID
int posx;
int posy;
};
static struct point_data point[MAX_SUPPORT_POINT];
struct i2c_dev
{
struct list_head list;
struct i2c_adapter *adap;
struct device *dev;
};
static struct i2c_driver pixcir_i2c_ts_driver;
static struct class *i2c_dev_class;
static LIST_HEAD( i2c_dev_list);
static DEFINE_SPINLOCK( i2c_dev_list_lock);
static void return_i2c_dev(struct i2c_dev *i2c_dev)
{
spin_lock(&i2c_dev_list_lock);
list_del(&i2c_dev->list);
spin_unlock(&i2c_dev_list_lock);
kfree(i2c_dev);
}
static struct i2c_dev *i2c_dev_get_by_minor(unsigned index)
{
struct i2c_dev *i2c_dev;
i2c_dev = NULL;
spin_lock(&i2c_dev_list_lock);
list_for_each_entry(i2c_dev, &i2c_dev_list, list)
{
if (i2c_dev->adap->nr == index)
goto found;
}
i2c_dev = NULL;
found: spin_unlock(&i2c_dev_list_lock);
return i2c_dev;
}
static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)
{
struct i2c_dev *i2c_dev;
if (adap->nr >= I2C_MINORS) {
printk(KERN_ERR "i2c-dev: Out of device minors (%d)\n",
adap->nr);
return ERR_PTR(-ENODEV);
}
i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev)
return ERR_PTR(-ENOMEM);
i2c_dev->adap = adap;
spin_lock(&i2c_dev_list_lock);
list_add_tail(&i2c_dev->list, &i2c_dev_list);
spin_unlock(&i2c_dev_list_lock);
return i2c_dev;
}
/*********************************Bee-0928-bottom**************************************/
struct pixcir_i2c_ts_data {
struct i2c_client *client;
struct input_dev *input,*input_key_dev;
int use_irq;
int gpio_pendown;
int gpio_reset;
int gpio_reset_active_low;
int pendown_iomux_mode;
int resetpin_iomux_mode;
char pendown_iomux_name[IOMUX_NAME_SIZE];
char resetpin_iomux_name[IOMUX_NAME_SIZE];
struct work_struct work;
//const struct pixcir_ts_platform_data *chip;
bool exiting;
struct early_suspend early_suspend;
};
#ifdef CONFIG_HAS_EARLYSUSPEND
static void pixcir_ts_early_suspend(struct early_suspend *h);
static void pixcir_ts_late_resume(struct early_suspend *h);
#endif
int tp_pixcir_write_reg(struct i2c_client *client,const char *buf ,int count)
{
struct i2c_msg msg[] = {
{
.addr = client->addr,
.flags = 0,
.len = count,
.buf = (char *)buf,
}
};
//ret = i2c_transfer(adap, &msg, 1);
if (i2c_transfer(client->adapter, msg, 1) < 0)
{
printk("write the address (0x%x) of the ssd2533 fail.",buf[0]);
return -1;
}
return 0;
}
int tp_pixcir_read_reg(struct i2c_client *client,u8 addr,u8 *buf,u8 len)
{
u8 msgbuf[1] = { addr };
struct i2c_msg msgs[] = {
{
.addr = client->addr,
.flags = 0, //Write
.len = 1,
.buf = msgbuf,
},
{
.addr = client->addr,
.flags = I2C_M_RD,
.len = len,
.buf = buf,
},
};
if (i2c_transfer(client->adapter, msgs, 2) < 0)
{
printk("read the address (0x%x) of the ssd2533 fail.",addr);
return -1;
}
return 0;
}
static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data)
{
struct pixcir_i2c_ts_data *tsdata = data;
u8 *p;
u8 touch, button;
u8 rdbuf[27], wrbuf[1] = { 0 };
int ret, i;
int ignore_cnt = 0;
ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf));
if (ret != sizeof(wrbuf)) {
dev_err(&tsdata->client->dev,
"%s: i2c_master_send failed(), ret=%d\n",
__func__, ret);
return;
}
ret = i2c_master_recv(tsdata->client, rdbuf, sizeof(rdbuf));
if (ret != sizeof(rdbuf)) {
dev_err(&tsdata->client->dev,
"%s: i2c_master_recv failed(), ret=%d\n",
__func__, ret);
return;
}
touch = rdbuf[0] & 0x07;
button = rdbuf[1];
p = &rdbuf[2];
for (i = 0; i < touch; i++) {
point[i].brn = (*(p + 4)) >> 3;
point[i].id = (*(p + 4)) & 0x7;
point[i].posx = (*(p + 1) << 8) + (*(p));
point[i].posy = (*(p + 3) << 8) + (*(p + 2));
p+=5;
}
if (touch) {
for(i=0; i < touch; i++) {
if (point[i].posy < 40 || point[i].posy > 520 || point[i].posx < 40) {
ignore_cnt++; //invalid point
continue;
}else {
point[i].posy -= 40;
point[i].posx -= 40;
if(point[i].posy < 0)
point[i].posy=1;
if(point[i].posx < 0)
point[i].posx=1;
input_mt_slot(tsdata->input, 0);
input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, true);
input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, 1);
input_report_abs(tsdata->input, ABS_MT_POSITION_X, point[i].posy);
input_report_abs(tsdata->input, ABS_MT_POSITION_Y, point[i].posx);
//input_sync(tsdata->input);
DBG("brn%d=%2d id%d=%1d x=%5d y=%5d \n",
i,point[i].brn,i,point[i].id,point[i].posy,point[i].posx);
}
}
if (touch == ignore_cnt)
return; //if all touchpoint are invalid, return
input_sync(tsdata->input);
}
}
static void pixcir_ts_work_func(struct work_struct *work)
{
struct pixcir_i2c_ts_data *tsdata = this_data;
//DBG("%s\n",__FUNCTION__);
while (!tsdata->exiting) {
pixcir_ts_poscheck(tsdata);
if (attb_read_val()){
DBG("%s: >>>>>touch release\n\n",__FUNCTION__);
enable_irq(tsdata->client->irq);
//input_report_key(tsdata->input, BTN_TOUCH, 0);
//input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, 0);
input_mt_slot(tsdata->input, 0);
input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, false);
//input_report_key(tsdata->input, ABS_MT_WIDTH_MAJOR,0);
break;
}
msleep(1);
}
input_sync(tsdata->input);
return;
}
static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
{
struct pixcir_i2c_ts_data *ts = dev_id;
DBG("%s: >>>>>>>>>\n",__FUNCTION__);
if(ts->use_irq){
disable_irq_nosync(ts->client->irq);
}
queue_work(pixcir_wq, &ts->work);
return IRQ_HANDLED;
}
#if 0
#ifdef CONFIG_PM_SLEEP
static int pixcir_i2c_ts_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
pixcir_dbg("%s\n",__FUNCTION__);
if (device_may_wakeup(&client->dev))
enable_irq_wake(client->irq);
return 0;
}
static int pixcir_i2c_ts_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
pixcir_dbg("%s\n",__FUNCTION__);
if (device_may_wakeup(&client->dev))
disable_irq_wake(client->irq);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume);
static int __devinit setup_resetPin(struct i2c_client *client, struct pixcir_i2c_ts_data *ts)
{
struct pixcir_platform_data *pdata = client->dev.platform_data;
int err;
pixcir_dbg("%s\n",__FUNCTION__);
ts->gpio_reset = pdata->gpio_reset;
ts->gpio_reset_active_low = pdata->gpio_reset_active_low;
ts->resetpin_iomux_mode = pdata->resetpin_iomux_mode;
///*
if(pdata->resetpin_iomux_name != NULL)
strcpy(ts->resetpin_iomux_name,pdata->resetpin_iomux_name);
//pixcir_dbg("%s=%d,%s,%d,%d\n",__FUNCTION__,ts->gpio_reset,ts->resetpin_iomux_name,ts->resetpin_iomux_mode,ts->gpio_reset_active_low);
if (!gpio_is_valid(ts->gpio_reset)) {
dev_err(&client->dev, "no gpio_reset?\n");
return -EINVAL;
}
rk29_mux_api_set(ts->resetpin_iomux_name,ts->resetpin_iomux_mode);
//*/
err = gpio_request(ts->gpio_reset, "pixcir_resetPin");
if (err) {
dev_err(&client->dev, "failed to request resetPin GPIO%d\n",
ts->gpio_reset);
return err;
}
err = gpio_direction_output(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
if (err) {
dev_err(&client->dev, "failed to pulldown resetPin GPIO%d,err%d\n",
ts->gpio_reset,err);
gpio_free(ts->gpio_reset);
return err;
}
mdelay(100);
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
mdelay(100);
return 0;
}
static int __devinit setup_pendown(struct i2c_client *client, struct pixcir_i2c_ts_data *ts)
{
int err;
struct pixcir_i2c_ts_data *pdata = client->dev.platform_data;
pixcir_dbg("%s\n",__FUNCTION__);
if (!client->irq) {
dev_dbg(&client->dev, "no IRQ?\n");
return -ENODEV;
}
if (!gpio_is_valid(pdata->gpio_pendown)) {
dev_err(&client->dev, "no gpio_pendown?\n");
return -EINVAL;
}
ts->gpio_pendown = pdata->gpio_pendown;
strcpy(ts->pendown_iomux_name,pdata->pendown_iomux_name);
ts->pendown_iomux_mode = pdata->pendown_iomux_mode;
pixcir_dbg("%s=%d,%s,%d\n",__FUNCTION__,ts->gpio_pendown,ts->pendown_iomux_name,ts->pendown_iomux_mode);
if (!gpio_is_valid(ts->gpio_pendown)) {
dev_err(&client->dev, "no gpio_pendown?\n");
return -EINVAL;
}
rk29_mux_api_set(ts->pendown_iomux_name,ts->pendown_iomux_mode);
err = gpio_request(ts->gpio_pendown, "gt801_pendown");
if (err) {
dev_err(&client->dev, "failed to request pendown GPIO%d\n",
ts->gpio_pendown);
return err;
}
err = gpio_pull_updown(ts->gpio_pendown, GPIOPullUp);
if (err) {
dev_err(&client->dev, "failed to pullup pendown GPIO%d\n",
ts->gpio_pendown);
gpio_free(ts->gpio_pendown);
return err;
}
return 0;
}
#endif
static ssize_t pixcir_proc_write(struct file *file, const char __user *buffer,
size_t count, loff_t *data)
{
char c;
int rc;
rc = get_user(c, buffer);
if (rc)
return rc;
if (c == '1')
ts_dbg_enable = 1;
else if (c == '0')
ts_dbg_enable = 0;
return count;
}
static const struct file_operations pixcir_proc_fops = {
.owner = THIS_MODULE,
.write = pixcir_proc_write,
};
static int __devinit pixcir_i2c_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
//const struct pixcir_ts_platform_data *pdata = client->dev.platform_data;
struct pixcir_i2c_ts_data *tsdata;
struct pixcir_platform_data *pdata;
struct device *dev;
struct i2c_dev *i2c_dev;
int error = 0;
struct proc_dir_entry *pixcir_proc_entry;
//if (!pdata) {
// dev_err(&client->dev, "platform data not defined\n");
// return -EINVAL;
//}
pixcir_dbg("%s\n",__FUNCTION__);
tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL);
tsdata->input = input_allocate_device();
if (!tsdata || !(tsdata->input)) {
dev_err(&client->dev, "Failed to allocate driver data!\n");
error = -ENOMEM;
goto err_free_mem;
}
pixcir_wq = create_singlethread_workqueue("pixcir_tp_wq");
if (!pixcir_wq) {
printk(KERN_ERR"%s: create workqueue failed\n", __FUNCTION__);
error = -ENOMEM;
goto err_free_mem;
}
INIT_WORK(&tsdata->work, pixcir_ts_work_func);
this_data = tsdata;
tsdata->exiting = false;
//tsdata->input = input;
//tsdata->chip = pdata;
tsdata->client = client;
i2c_set_clientdata(client, tsdata);
pdata = client->dev.platform_data;
//error = setup_resetPin(client,tsdata);
if(error)
{
printk("%s:setup_resetPin fail\n",__FUNCTION__);
goto err_free_mem;
}
tsdata->input->phys = "/dev/input/event2";
tsdata->input->name = "pixcir_ts-touchscreen";//client->name;
tsdata->input->id.bustype = BUS_I2C;
tsdata->input->dev.parent = &client->dev;
///*
/*set_bit(EV_SYN, tsdata->input->evbit);
set_bit(EV_KEY, tsdata->input->evbit);
set_bit(EV_ABS, tsdata->input->evbit);
set_bit(BTN_TOUCH, tsdata->input->keybit);
set_bit(BTN_2, tsdata->input->keybit);//*/
//tsdata->input->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_ABS) ;
//tsdata->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
/*tsdata->input->absbit[0] = BIT_MASK(ABS_MT_POSITION_X) | BIT_MASK(ABS_MT_POSITION_Y) |
BIT_MASK(ABS_MT_TOUCH_MAJOR) | BIT_MASK(ABS_MT_WIDTH_MAJOR); // for android*/
//tsdata->input->keybit[BIT_WORD(BTN_START)] = BIT_MASK(BTN_START);
//input_set_abs_params(input, ABS_X, 0, X_MAX, 0, 0);
//input_set_abs_params(input, ABS_Y, 0, Y_MAX, 0, 0);
__set_bit(INPUT_PROP_DIRECT, tsdata->input->propbit);
__set_bit(EV_ABS, tsdata->input->evbit);
input_mt_init_slots(tsdata->input, MAX_SUPPORT_POINT);
input_set_abs_params(tsdata->input, ABS_MT_POSITION_X, pdata->x_min, pdata->x_max, 0, 0);
input_set_abs_params(tsdata->input, ABS_MT_POSITION_Y, pdata->y_min, pdata->y_max, 0, 0);
//input_set_abs_params(tsdata->input, ABS_MT_WIDTH_MAJOR, 0, 16, 0, 0);
//input_set_abs_params(tsdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
input_set_abs_params(tsdata->input, ABS_MT_TOUCH_MAJOR, 0, 1, 0, 0);
//input_set_abs_params(tsdata->input, ABS_MT_TRACKING_ID, 0, 5, 0, 0);
input_set_drvdata(tsdata->input, tsdata);
//init int and reset ports
error = gpio_request(client->irq, "TS_INT"); //Request IO
if (error){
dev_err(&client->dev, "Failed to request GPIO:%d, ERRNO:%d\n",(int)client->irq, error);
goto err_free_mem;
}
rk29_mux_api_set(pdata->pendown_iomux_name, pdata->pendown_iomux_mode);
gpio_direction_input(client->irq);
gpio_set_value(client->irq,GPIO_HIGH);
gpio_pull_updown(client->irq, 0);
error = gpio_request(pdata->gpio_reset, "pixcir_resetPin");
if(error){
dev_err(&client->dev, "failed to request resetPin GPIO%d\n", pdata->gpio_reset);
goto err_free_mem;
}
rk29_mux_api_set(pdata->resetpin_iomux_name, pdata->resetpin_iomux_mode);
/*{
gpio_pull_updown(pdata->gpio_reset, 1);
gpio_direction_output(pdata->gpio_reset, 0);
msleep(20); //delay at least 1ms
gpio_direction_input(pdata->gpio_reset);
gpio_pull_updown(pdata->gpio_reset, 0);
msleep(120);
}*/
gpio_pull_updown(pdata->gpio_reset, 1);
mdelay(20);
gpio_direction_output(pdata->gpio_reset, 0);
gpio_set_value(pdata->gpio_reset,GPIO_HIGH);//GPIO_LOW
mdelay(100);
gpio_set_value(pdata->gpio_reset,GPIO_LOW);//GPIO_HIGH
mdelay(120);
// gpio_direction_input(pdata->gpio_reset);
printk("pdata->gpio_reset = %d\n",gpio_get_value(pdata->gpio_reset));
//printk("ts->gpio_irq = %d\n",gpio_get_value(pdata->gpio_pendown));
printk("pdata->gpio_pendown = %d\n",gpio_get_value(client->irq));
#if 0
//**********************************************
char buffer[2];
buffer[0] = 0x3A;
buffer[1] = 0x03;
tp_pixcir_write_reg(client,buffer,2);
ssleep(6);
//********************************************************//
#endif
client->irq = gpio_to_irq(client->irq);
error = request_irq(client->irq, pixcir_ts_isr, IRQF_TRIGGER_FALLING, client->name, (void *)tsdata);
if (error)
dev_err(&client->dev, "request_irq failed\n");
/*
error = request_threaded_irq(client->irq, NULL, pixcir_ts_isr,
IRQF_TRIGGER_FALLING,
client->name, tsdata);*/
tsdata->use_irq = 1;
if (error) {
dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
tsdata->use_irq = 0;
goto err_free_mem;
}
error = input_register_device(tsdata->input);
if (error)
goto err_free_irq;
i2c_set_clientdata(client, tsdata);
device_init_wakeup(&client->dev, 1);
/*********************************Bee-0928-TOP****************************************/
i2c_dev = get_free_i2c_dev(client->adapter);
if (IS_ERR(i2c_dev)) {
error = PTR_ERR(i2c_dev);
return error;
}
dev = device_create(i2c_dev_class, &client->adapter->dev, MKDEV(I2C_MAJOR,
client->adapter->nr), NULL, "pixcir_i2c_ts%d", 0);
if (IS_ERR(dev)) {
error = PTR_ERR(dev);
return error;
}
/*********************************Bee-0928-BOTTOM****************************************/
#ifdef CONFIG_HAS_EARLYSUSPEND
tsdata->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
tsdata->early_suspend.suspend = pixcir_ts_early_suspend;
tsdata->early_suspend.resume = pixcir_ts_late_resume;
register_early_suspend(&tsdata->early_suspend);
#endif
pixcir_proc_entry = proc_create("driver/pixcir", 0777, NULL, &pixcir_proc_fops);
dev_err(&tsdata->client->dev, "insmod successfully!\n");
return 0;
err_free_irq:
free_irq(client->irq, tsdata);
err_free_mem:
input_free_device(tsdata->input);
kfree(tsdata);
return error;
}
static int __devexit pixcir_i2c_ts_remove(struct i2c_client *client)
{
int error;
struct i2c_dev *i2c_dev;
struct pixcir_i2c_ts_data *tsdata = i2c_get_clientdata(client);
unregister_early_suspend(&tsdata->early_suspend);
device_init_wakeup(&client->dev, 0);
tsdata->exiting = true;
mb();
free_irq(client->irq, tsdata);
/*********************************Bee-0928-TOP****************************************/
i2c_dev = get_free_i2c_dev(client->adapter);
if (IS_ERR(i2c_dev)) {
error = PTR_ERR(i2c_dev);
return error;
}
return_i2c_dev(i2c_dev);
device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, client->adapter->nr));
/*********************************Bee-0928-BOTTOM****************************************/
input_unregister_device(tsdata->input);
kfree(tsdata);
return 0;
}
/*************************************Bee-0928****************************************/
/* pixcir_open */
/*************************************Bee-0928****************************************/
static int pixcir_open(struct inode *inode, struct file *file)
{
int subminor;
struct i2c_client *client;
struct i2c_adapter *adapter;
struct i2c_dev *i2c_dev;
int ret = 0;
#if PIXCIR_DEBUG
printk("enter pixcir_open function\n");
#endif
subminor = iminor(inode);
//lock_kernel();
i2c_dev = i2c_dev_get_by_minor(subminor);
if (!i2c_dev) {
printk("error i2c_dev\n");
return -ENODEV;
}
adapter = i2c_get_adapter(i2c_dev->adap->nr);
if (!adapter) {
return -ENODEV;
}
client = kzalloc(sizeof(*client), GFP_KERNEL);
if (!client) {
i2c_put_adapter(adapter);
ret = -ENOMEM;
}
snprintf(client->name, I2C_NAME_SIZE, "pixcir_i2c_ts%d", adapter->nr);
client->driver = &pixcir_i2c_ts_driver;
client->adapter = adapter;
file->private_data = client;
return 0;
}
/*************************************Bee-0928****************************************/
/* pixcir_ioctl */
/*************************************Bee-0928****************************************/
static long pixcir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
//printk("ioctl function\n");
struct i2c_client *client = (struct i2c_client *) file->private_data;
#if PIXCIR_DEBUG
printk("cmd = %d,arg = %d\n", cmd, arg);
#endif
switch (cmd)
{
case CALIBRATION_FLAG: //CALIBRATION_FLAG = 1
#if PIXCIR_DEBUG
printk("CALIBRATION\n");
#endif
client->addr = SLAVE_ADDR;
status_reg = 0;
status_reg = CALIBRATION_FLAG;
break;
default:
break;//return -ENOTTY;
}
return 0;
}
/***********************************Bee-0928****************************************/
/* pixcir_write */
/***********************************Bee-0928****************************************/
static ssize_t pixcir_write(struct file *file,const char __user *buf,size_t count, loff_t *ppos)
{
struct i2c_client *client;
char *tmp;
static int ret=0;
pixcir_dbg("%s\n",__FUNCTION__);
client = file->private_data;
//printk("pixcir_write function\n");
switch(status_reg)
{
case CALIBRATION_FLAG: //CALIBRATION_FLAG=1
tmp = kmalloc(count,GFP_KERNEL);
if (tmp==NULL)
return -ENOMEM;
if (copy_from_user(tmp,buf,count)) {
printk("CALIBRATION_FLAG copy_from_user error\n");
kfree(tmp);
return -EFAULT;
}
ret = i2c_master_send(client,tmp,count);
if (ret!=count ) {
dev_err(&client->dev,
"%s: i2c_master_recv failed(), ret=%d\n",
__func__, ret);
}
while(!attb_read_val());//waiting to finish the calibration.(pixcir application_note_710_v3 p43)
kfree(tmp);
status_reg = 0;
break;
default:
break;
}
return ret;
}
/***********************************Bee-0928****************************************/
/* pixcir_release */
/***********************************Bee-0928****************************************/
static int pixcir_release(struct inode *inode, struct file *file)
{
struct i2c_client *client = file->private_data;
#if PIXCIR_DEBUG
printk("enter pixcir_release funtion\n");
#endif
i2c_put_adapter(client->adapter);
kfree(client);
file->private_data = NULL;
return 0;
}
/*********************************Bee-0928-TOP****************************************/
static const struct file_operations pixcir_i2c_ts_fops =
{ .owner = THIS_MODULE,
.write = pixcir_write,
.open = pixcir_open,
.unlocked_ioctl = pixcir_ioctl,
.release = pixcir_release,
};
/*********************************Bee-0928-BOTTOM****************************************/
static int pixcir_ts_suspend(struct i2c_client *client, pm_message_t mesg)
{
struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
DBG("%s\n",__FUNCTION__);
if (ts->use_irq)
disable_irq(client->irq);
//gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
return 0;
}
static int pixcir_ts_resume(struct i2c_client *client)
{
struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
DBG("%s\n",__FUNCTION__);
if (ts->use_irq)
enable_irq(client->irq);
//gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
return 0;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void pixcir_ts_early_suspend(struct early_suspend *h)
{
struct pixcir_i2c_ts_data *ts;
DBG("%s\n",__FUNCTION__);
ts = container_of(h, struct pixcir_i2c_ts_data, early_suspend);
pixcir_ts_suspend(ts->client, PMSG_SUSPEND);
}
static void pixcir_ts_late_resume(struct early_suspend *h)
{
struct pixcir_i2c_ts_data *ts;
DBG("%s\n",__FUNCTION__);
ts = container_of(h, struct pixcir_i2c_ts_data, early_suspend);
pixcir_ts_resume(ts->client);
}
#endif
static const struct i2c_device_id pixcir_i2c_ts_id[] = {
{ "pixcir_ts", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id);
static struct i2c_driver pixcir_i2c_ts_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "pixcir_ts",
//.pm = &pixcir_dev_pm_ops,
},
#ifndef CONFIG_HAS_EARLYSUSPEND
.suspend = pixcir_ts_suspend,
.resume = pixcir_ts_resume,
#endif
.probe = pixcir_i2c_ts_probe,
.remove = __devexit_p(pixcir_i2c_ts_remove),
.id_table = pixcir_i2c_ts_id,
};
static int __init pixcir_i2c_ts_init(void)
{
int ret;
pixcir_dbg("%s\n",__FUNCTION__);
pixcir_wq = create_singlethread_workqueue("pixcir_wq");
if (!pixcir_wq)
return -ENOMEM;
/*********************************Bee-0928-TOP****************************************/
ret = register_chrdev(I2C_MAJOR,"pixcir_i2c_ts",&pixcir_i2c_ts_fops);
if (ret) {
printk(KERN_ERR "%s:register chrdev failed\n",__FILE__);
return ret;
}
i2c_dev_class = class_create(THIS_MODULE, "pixcir_i2c_dev");
if (IS_ERR(i2c_dev_class)) {
ret = PTR_ERR(i2c_dev_class);
class_destroy(i2c_dev_class);
}
/********************************Bee-0928-BOTTOM******************************************/
//tangoC_init();
return i2c_add_driver(&pixcir_i2c_ts_driver);
}
module_init(pixcir_i2c_ts_init);
static void __exit pixcir_i2c_ts_exit(void)
{
i2c_del_driver(&pixcir_i2c_ts_driver);
if (pixcir_wq)
destroy_workqueue(pixcir_wq);
/********************************Bee-0928-TOP******************************************/
class_destroy(i2c_dev_class);
unregister_chrdev(I2C_MAJOR,"pixcir_i2c_ts");
/********************************Bee-0928-BOTTOM******************************************/
}
module_exit(pixcir_i2c_ts_exit);
MODULE_AUTHOR("Jianchun Bian <jcbian@pixcir.com.cn>");
MODULE_DESCRIPTION("Pixcir I2C Touchscreen Driver");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,74 @@
#ifndef __DRIVERS_TOUCHSCREEN_PIXCIR_TS_H
#define __DRIVERS_TOUCHSCREEN_PIXCIR_TS_H
// #include <mach/gpio.h>
static int attb_read_val(void);
static void tangoC_init(void);
#define X_MAX 480
#define Y_MAX 800
#define MAX_SUPPORT_POINT 5
#define IOMUX_NAME_SIZE 48
struct pixcir_platform_data {
u16 model; /*. */
bool swap_xy; /* swap x and y axes */
u16 x_min, x_max;
u16 y_min, y_max;
int gpio_reset;
int gpio_reset_active_low;
int gpio_pendown; /* the GPIO used to decide the pendown */
char pendown_iomux_name[IOMUX_NAME_SIZE];
char resetpin_iomux_name[IOMUX_NAME_SIZE];
int pendown_iomux_mode;
int resetpin_iomux_mode;
uint8_t virtual_key_num;
uint16_t virtual_key_code[4];
int (*get_pendown_state)(void);
};
//Platform gpio define
//#define S5PC1XX
#ifdef S5PC1XX
#include <plat/gpio-bank-e1.h> //reset pin GPE1_5
#include <plat/gpio-bank-h1.h> //attb pin GPH1_3
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#define ATTB S5PC1XX_GPH1(3)
#define get_attb_value gpio_get_value
#define RESETPIN_CFG s3c_gpio_cfgpin(S5PC1XX_GPE1(5),S3C_GPIO_OUTPUT)
#define RESETPIN_SET0 gpio_direction_output(S5PC1XX_GPE1(5),0)
#define RESETPIN_SET1 gpio_direction_output(S5PC1XX_GPE1(5),1)
#else //mini6410
// #include <plat/gpio-cfg.h>
// #include <mach/gpio-bank-e.h>
// #include <mach/gpio-bank-n.h>
// #include <mach/gpio.h>
#define ATTB RK29_PIN4_PD5
#define get_attb_value gpio_get_value
#define RESETPIN_CFG //s3c_gpio_cfgpin(RK29_PIN4_PD5,S3C_GPIO_OUTPUT)
//rk29_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE_GPIO);
#define RESETPIN_SET0 gpio_direction_output(RK29_PIN4_PD5,0)
#define RESETPIN_SET1 gpio_direction_output(RK29_PIN4_PD5,1)
#endif
static int attb_read_val(void)
{
return gpio_get_value(RK29_PIN4_PD5);
}
/*static void tangoC_init(void)
{
RESETPIN_SET0;
}*/
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,232 @@
/*
* include/linux/goodix_touch.h
*
* Copyright (C) 2010 - 2011 Goodix, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef _LINUX_GOODIX_TOUCH_H
#define _LINUX_GOODIX_TOUCH_H
#include <linux/earlysuspend.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/input.h>
//*************************TouchScreen Work Part*****************************
#define GOODIX_I2C_NAME "Goodix-TS"
#define GOODIX_1024X768 1
#define TS_MAX_X 1024
#define TS_MAX_Y 768
#if 1
#define INT_PORT RK29_PIN0_PA2
#ifdef INT_PORT
#define TS_INT gpio_to_irq(INT_PORT)
// #define INT_CFG S3C_GPIO_SFN(2) //IO configer as EINT
#else
#define TS_INT 0
#endif
//whether need send cfg?
//#define DRIVER_SEND_CFG
//set trigger mode
#define INT_TRIGGER 0
#endif
#define POLL_TIME 10 //actual query spacing interval:POLL_TIME+6
#define GOODIX_MULTI_TOUCH
#ifdef GOODIX_MULTI_TOUCH
#define MAX_FINGER_NUM 10
#else
#define MAX_FINGER_NUM 1
#endif
//#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
struct rk_touch_info
{
u32 status; // 1:down,0:up
u32 x ;
u32 y ;
} ;
struct rk_ts_data{
uint16_t addr;
uint8_t bad_data;
struct i2c_client *client;
struct input_dev *input_dev;
int use_reset; //use RESET flag
int use_irq; //use EINT flag
int irq;
int irq_pin;
int read_mode; //read moudle mode,20110221 by andrew
struct hrtimer timer;
struct workqueue_struct *ts_wq;
struct delayed_work ts_work;
char phys[32];
int retry;
struct early_suspend early_suspend;
int (*power)(struct rk_ts_data * ts, int on);
int (*ts_init)(struct rk_ts_data*ts);
int (*input_parms_init)(struct rk_ts_data *ts);
void (*get_touch_info)(struct rk_ts_data *ts,char *point_num,struct rk_touch_info *info_buf); //get touch data info
uint16_t abs_x_max;
uint16_t abs_y_max;
uint8_t max_touch_num;
uint8_t int_trigger_type;
bool pendown;
};
struct goodix_ts_data {
uint16_t addr;
uint8_t bad_data;
struct i2c_client *client;
struct input_dev *input_dev;
int use_reset; //use RESET flag
int use_irq; //use EINT flag
int read_mode; //read moudle mode,20110221 by andrew
struct hrtimer timer;
struct delayed_work work;
char phys[32];
int retry;
struct early_suspend early_suspend;
int (*power)(struct goodix_ts_data * ts, int on);
uint16_t abs_x_max;
uint16_t abs_y_max;
uint8_t max_touch_num;
uint8_t int_trigger_type;
bool pendown;
};
static const char *rk_ts_name = "Goodix Capacitive TouchScreen";
static struct workqueue_struct *goodix_wq;
struct i2c_client * i2c_connect_client = NULL;
static struct proc_dir_entry *goodix_proc_entry;
//static struct kobject *goodix_debug_kobj;
#ifdef CONFIG_HAS_EARLYSUSPEND
static void goodix_ts_early_suspend(struct early_suspend *h);
static void goodix_ts_late_resume(struct early_suspend *h);
#endif
#define READ_COOR_ADDR 0x01
//*****************************End of Part I *********************************
//*************************Touchkey Surpport Part*****************************
//#define HAVE_TOUCH_KEY
#ifdef HAVE_TOUCH_KEY
#define READ_COOR_ADDR 0x00
const uint16_t touch_key_array[]={
KEY_MENU, //MENU
KEY_HOME, //HOME
KEY_SEND //CALL
};
#define MAX_KEY_NUM (sizeof(touch_key_array)/sizeof(touch_key_array[0]))
#else
#define READ_COOR_ADDR 0x01
#endif
//*****************************End of Part II*********************************
#if 1
//*************************Firmware Update part*******************************
#define CONFIG_TOUCHSCREEN_GOODIX_IAP
#ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
#define UPDATE_NEW_PROTOCOL
unsigned int oldcrc32 = 0xFFFFFFFF;
unsigned int crc32_table[256];
unsigned int ulPolynomial = 0x04c11db7;
unsigned char rd_cfg_addr;
unsigned char rd_cfg_len;
unsigned char g_enter_isp = 0;
static int goodix_update_write(struct file *filp, const char __user *buff, unsigned long len, void *data);
static int goodix_update_read( char *page, char **start, off_t off, int count, int *eof, void *data );
#define PACK_SIZE 64 //update file package size
#define MAX_TIMEOUT 60000 //update time out conut
#define MAX_I2C_RETRIES 20 //i2c retry times
//I2C buf address
#define ADDR_CMD 80
#define ADDR_STA 81
#ifdef UPDATE_NEW_PROTOCOL
#define ADDR_DAT 0
#else
#define ADDR_DAT 82
#endif
//moudle state
#define NEW_UPDATE_START 0x01
#define UPDATE_START 0x02
#define SLAVE_READY 0x08
#define UNKNOWN_ERROR 0x00
#define FRAME_ERROR 0x10
#define CHECKSUM_ERROR 0x20
#define TRANSLATE_ERROR 0x40
#define FLASH_ERROR 0X80
//error no
#define ERROR_NO_FILE 2 //ENOENT
#define ERROR_FILE_READ 23 //ENFILE
#define ERROR_FILE_TYPE 21 //EISDIR
#define ERROR_GPIO_REQUEST 4 //EINTR
#define ERROR_I2C_TRANSFER 5 //EIO
#define ERROR_NO_RESPONSE 16 //EBUSY
#define ERROR_TIMEOUT 110 //ETIMEDOUT
//update steps
#define STEP_SET_PATH 1
#define STEP_CHECK_FILE 2
#define STEP_WRITE_SYN 3
#define STEP_WAIT_SYN 4
#define STEP_WRITE_LENGTH 5
#define STEP_WAIT_READY 6
#define STEP_WRITE_DATA 7
#define STEP_READ_STATUS 8
#define FUN_CLR_VAL 9
#define FUN_CMD 10
#define FUN_WRITE_CONFIG 11
//fun cmd
#define CMD_DISABLE_TP 0
#define CMD_ENABLE_TP 1
#define CMD_READ_VER 2
#define CMD_READ_RAW 3
#define CMD_READ_DIF 4
#define CMD_READ_CFG 5
#define CMD_SYS_REBOOT 101
//read mode
#define MODE_RD_VER 1
#define MODE_RD_RAW 2
#define MODE_RD_DIF 3
#define MODE_RD_CFG 4
#endif
//*****************************End of Part III********************************
#endif
struct goodix_i2c_platform_data {
uint32_t version; /* Use this entry for panels with */
//reservation
};
#endif /* _LINUX_GOODIX_TOUCH_H */

View File

@@ -1447,7 +1447,7 @@ sensor_power_end:
}
static int sensor_init(struct v4l2_subdev *sd, u32 val)
{
struct i2c_client *client = sd->priv;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_device *icd = client->dev.platform_data;
struct sensor *sensor = to_sensor(client);
const struct v4l2_queryctrl *qctrl;
@@ -1643,7 +1643,7 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)
static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
{
struct i2c_client *client = sd->priv;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_device *icd = client->dev.platform_data;
struct sensor *sensor = to_sensor(client);
@@ -1692,7 +1692,7 @@ static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefm
}
static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
{
struct i2c_client *client = sd->priv;
struct i2c_client *client = v4l2_get_subdevdata(sd);
const struct sensor_datafmt *fmt;
struct sensor *sensor = to_sensor(client);
const struct v4l2_queryctrl *qctrl;
@@ -1835,7 +1835,7 @@ sensor_s_fmt_end:
static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
{
struct i2c_client *client = sd->priv;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct sensor *sensor = to_sensor(client);
const struct sensor_datafmt *fmt;
int ret = 0;
@@ -1864,7 +1864,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
{
struct i2c_client *client = sd->priv;
struct i2c_client *client = v4l2_get_subdevdata(sd);
if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
return -EINVAL;
@@ -2148,7 +2148,7 @@ static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_que
static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct i2c_client *client = sd->priv;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct sensor *sensor = to_sensor(client);
const struct v4l2_queryctrl *qctrl;
@@ -2207,7 +2207,7 @@ static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct i2c_client *client = sd->priv;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct sensor *sensor = to_sensor(client);
struct soc_camera_device *icd = client->dev.platform_data;
const struct v4l2_queryctrl *qctrl;
@@ -2497,7 +2497,7 @@ static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_c
static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
{
struct i2c_client *client = sd->priv;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_device *icd = client->dev.platform_data;
int i, error_cnt=0, error_idx=-1;
@@ -2522,7 +2522,7 @@ static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_control
static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
{
struct i2c_client *client = sd->priv;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_device *icd = client->dev.platform_data;
int i, error_cnt=0, error_idx=-1;
@@ -2599,7 +2599,7 @@ sensor_video_probe_err:
}
static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
struct i2c_client *client = sd->priv;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_device *icd = client->dev.platform_data;
struct sensor *sensor = to_sensor(client);
int ret = 0;

View File

@@ -97,6 +97,7 @@ static struct rk29camera_platform_data rk29_camera_platform_data = {
.gpio_flash = CONFIG_SENSOR_FALSH_PIN_0,
.gpio_flag = (CONFIG_SENSOR_POWERACTIVE_LEVEL_0|CONFIG_SENSOR_RESETACTIVE_LEVEL_0|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_0|CONFIG_SENSOR_FLASHACTIVE_LEVEL_0),
.gpio_init = 0,
.orientation = CONFIG_SENSOR_ORIENTATION_0,
.dev_name = SENSOR_DEVICE_NAME_0,
}, {
.gpio_reset = CONFIG_SENSOR_RESET_PIN_1,
@@ -105,6 +106,7 @@ static struct rk29camera_platform_data rk29_camera_platform_data = {
.gpio_flash = CONFIG_SENSOR_FALSH_PIN_1,
.gpio_flag = (CONFIG_SENSOR_POWERACTIVE_LEVEL_1|CONFIG_SENSOR_RESETACTIVE_LEVEL_1|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_1|CONFIG_SENSOR_FLASHACTIVE_LEVEL_1),
.gpio_init = 0,
.orientation = CONFIG_SENSOR_ORIENTATION_1,
.dev_name = SENSOR_DEVICE_NAME_1,
}
},
@@ -1432,7 +1434,6 @@ static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd,
}
break;
}
default:
{
printk("%s cmd(0x%x) is unknown!\n",__FUNCTION__, cmd);

View File

@@ -48,7 +48,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
printk(KERN_WARNING"rk29xx_camera: " fmt , ## arg); } while (0)
#define RK29CAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
#define RK29CAMERA_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
#define RK29CAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
// VIP Reg Offset
#define RK29_VIP_AHBR_CTRL 0x00
@@ -1528,8 +1528,16 @@ static unsigned int rk29_camera_poll(struct file *file, poll_table *pt)
static int rk29_camera_querycap(struct soc_camera_host *ici,
struct v4l2_capability *cap)
{
/* cap->name is set by the firendly caller:-> */
strlcpy(cap->card, rk29_cam_driver_description, sizeof(cap->card));
struct rk29_camera_dev *pcdev = ici->priv;
char orientation[5];
strlcpy(cap->card, dev_name(pcdev->icd->pdev), sizeof(cap->card));
if (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->gpio_res[0].dev_name) == 0) {
sprintf(orientation,"-%d",pcdev->pdata->gpio_res[0].orientation);
} else {
sprintf(orientation,"-%d",pcdev->pdata->gpio_res[1].orientation);
}
strcat(cap->card,orientation);
cap->version = RK29_CAM_VERSION_CODE;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;

32
drivers/mfd/wm831x-core.c Normal file → Executable file
View File

@@ -1460,7 +1460,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
int rev;
enum wm831x_parent parent;
int ret, i;
int ret;
mutex_init(&wm831x->io_lock);
mutex_init(&wm831x->key_lock);
@@ -1558,15 +1558,6 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev);
break;
<<<<<<< HEAD
case WM8326:
parent = WM8326;
wm831x->num_gpio = 12;
dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev);
break;
=======
>>>>>>> parent of 15f7fab... temp revert rk change
default:
dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
ret = -EINVAL;
@@ -1601,17 +1592,6 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
}
}
if (pdata) {
for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
if (!pdata->gpio_defaults[i])
continue;
wm831x_reg_write(wm831x,
WM831X_GPIO1_CONTROL + i,
pdata->gpio_defaults[i] & 0xffff);
}
}
ret = wm831x_irq_init(wm831x, irq);
if (ret != 0)
goto err;
@@ -1647,9 +1627,12 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
break;
case WM8320:
ret = mfd_add_devices(wm831x->dev, -1,
wm8320_devs, ARRAY_SIZE(wm8320_devs),
NULL, 0);
break;
case WM8321:
case WM8325:
case WM8326:
ret = mfd_add_devices(wm831x->dev, -1,
wm8320_devs, ARRAY_SIZE(wm8320_devs),
NULL, 0);
@@ -1766,8 +1749,6 @@ int wm831x_device_suspend(struct wm831x *wm831x)
return 0;
}
<<<<<<< HEAD
=======
void wm831x_enter_sleep(void){
#if 1//def CONFIG_RK2818_SOC_PM
struct regulator *dcdc;
@@ -1861,7 +1842,6 @@ int wm831x_device_restart(struct wm831x *wm831x)
return 0;
}
>>>>>>> parent of 15f7fab... temp revert rk change
MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC");
MODULE_LICENSE("GPL");

59
drivers/mfd/wm831x-i2c.c Normal file → Executable file
View File

@@ -52,27 +52,6 @@ static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
int bytes, void *src)
{
struct i2c_client *i2c = wm831x->control_data;
<<<<<<< HEAD
struct i2c_msg xfer[2];
int ret;
reg = cpu_to_be16(reg);
xfer[0].addr = i2c->addr;
xfer[0].flags = 0;
xfer[0].len = 2;
xfer[0].buf = (char *)&reg;
xfer[1].addr = i2c->addr;
xfer[1].flags = I2C_M_NOSTART;
xfer[1].len = bytes;
xfer[1].buf = (char *)src;
ret = i2c_transfer(i2c->adapter, xfer, 2);
if (ret < 0)
return ret;
if (ret != 2)
=======
unsigned char msg[bytes + 2];
int ret;
@@ -84,7 +63,6 @@ static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
if (ret < 0)
return ret;
if (ret < bytes + 2)
>>>>>>> parent of 15f7fab... temp revert rk change
return -EIO;
return 0;
@@ -94,19 +72,13 @@ static int wm831x_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm831x *wm831x;
<<<<<<< HEAD
=======
int ret,gpio,irq;
>>>>>>> parent of 15f7fab... temp revert rk change
wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
if (wm831x == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, wm831x);
<<<<<<< HEAD
=======
gpio = i2c->irq;
ret = gpio_request(gpio, "wm831x");
@@ -121,17 +93,12 @@ static int wm831x_i2c_probe(struct i2c_client *i2c,
}
irq = gpio_to_irq(gpio);
>>>>>>> parent of 15f7fab... temp revert rk change
wm831x->dev = &i2c->dev;
wm831x->control_data = i2c;
wm831x->read_dev = wm831x_i2c_read_device;
wm831x->write_dev = wm831x_i2c_write_device;
<<<<<<< HEAD
return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
=======
return wm831x_device_init(wm831x, id->driver_data, irq);
>>>>>>> parent of 15f7fab... temp revert rk change
}
static int wm831x_i2c_remove(struct i2c_client *i2c)
@@ -143,16 +110,16 @@ static int wm831x_i2c_remove(struct i2c_client *i2c)
return 0;
}
static int wm831x_i2c_suspend(struct device *dev)
static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
{
struct wm831x *wm831x = dev_get_drvdata(dev);
struct wm831x *wm831x = i2c_get_clientdata(i2c);
return wm831x_device_suspend(wm831x);
}
static int wm831x_i2c_resume(struct device *dev)
static int wm831x_i2c_resume(struct i2c_client *i2c)
{
struct wm831x *wm831x = dev_get_drvdata(dev);
struct wm831x *wm831x = i2c_get_clientdata(i2c);
int i;
//set some intterupt again while resume
for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {
@@ -184,24 +151,20 @@ static const struct i2c_device_id wm831x_i2c_id[] = {
{ "wm8320", WM8320 },
{ "wm8321", WM8321 },
{ "wm8325", WM8325 },
{ "wm8326", WM8326 },
{ }
};
MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id);
static const struct dev_pm_ops wm831x_pm_ops = {
.suspend = wm831x_i2c_suspend,
.resume = wm831x_i2c_resume,
};
static struct i2c_driver wm831x_i2c_driver = {
.driver = {
.name = "wm831x",
.owner = THIS_MODULE,
.pm = &wm831x_pm_ops,
.name = "wm831x",
.owner = THIS_MODULE,
},
.probe = wm831x_i2c_probe,
.remove = wm831x_i2c_remove,
.suspend = wm831x_i2c_suspend,
.resume = wm831x_i2c_resume,
.shutdown = wm831x_i2c_shutdown,
.id_table = wm831x_i2c_id,
};
@@ -209,7 +172,6 @@ static struct i2c_driver wm831x_i2c_driver = {
static int __init wm831x_i2c_init(void)
{
int ret;
printk("%s \n", __FUNCTION__);
ret = i2c_add_driver(&wm831x_i2c_driver);
if (ret != 0)
@@ -217,8 +179,9 @@ static int __init wm831x_i2c_init(void)
return ret;
}
subsys_initcall(wm831x_i2c_init);
//subsys_initcall(wm831x_i2c_init);
//fs_initcall(wm831x_i2c_init);
subsys_initcall_sync(wm831x_i2c_init);
static void __exit wm831x_i2c_exit(void)
{
i2c_del_driver(&wm831x_i2c_driver);

View File

@@ -18,15 +18,13 @@
#include <linux/irq.h>
#include <linux/mfd/core.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/pdata.h>
#include <linux/mfd/wm831x/gpio.h>
#include <linux/mfd/wm831x/irq.h>
#include <linux/delay.h>
<<<<<<< HEAD
=======
#include <linux/wakelock.h>
/*
* Since generic IRQs don't currently support interrupt controllers on
@@ -37,7 +35,6 @@
* interrupts, but hopefully won't last too long.
*/
#define WM831X_IRQ_TYPE IRQF_TRIGGER_LOW
>>>>>>> parent of 15f7fab... temp revert rk change
struct wm831x_irq_data {
int primary;
@@ -405,28 +402,13 @@ static void wm831x_irq_disable(struct irq_data *data)
//printk("%s:irq=%d\n",__FUNCTION__,irq);
}
static void wm831x_irq_disable(unsigned int irq)
{
struct wm831x *wm831x = get_irq_chip_data(irq);
struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq);
wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
//printk("%s:irq=%d\n",__FUNCTION__,irq);
}
static int wm831x_irq_set_type(struct irq_data *data, unsigned int type)
{
struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
int val, irq;
int val, irq = 0;
<<<<<<< HEAD
irq = data->irq - wm831x->irq_base;
if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) {
=======
irq = irq - wm831x->irq_base;
if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_12) {
>>>>>>> parent of 15f7fab... temp revert rk change
/* Ignore internal-only IRQs */
if (irq >= 0 && irq < WM831X_NUM_IRQS)
return 0;
@@ -452,17 +434,17 @@ static int wm831x_irq_set_type(struct irq_data *data, unsigned int type)
WM831X_GPN_INT_MODE | WM831X_GPN_POL, val);
}
static int wm831x_irq_set_wake(unsigned irq, unsigned state)
static int wm831x_irq_set_wake(struct irq_data *data, unsigned state)
{
struct wm831x *wm831x = get_irq_chip_data(irq);
struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
int irq = data->irq;
//only wm831x irq
if ((irq > wm831x->irq_base + WM831X_IRQ_TEMP_THW) &&( irq < wm831x->irq_base + WM831X_NUM_IRQS))
{
if(state)
wm831x_irq_unmask(irq);
wm831x_irq_enable(data);
else
wm831x_irq_mask(irq);
wm831x_irq_disable(data);
return 0;
}
else
@@ -475,23 +457,13 @@ static int wm831x_irq_set_wake(unsigned irq, unsigned state)
}
static struct irq_chip wm831x_irq_chip = {
<<<<<<< HEAD
.name = "wm831x",
.irq_bus_lock = wm831x_irq_lock,
.irq_bus_sync_unlock = wm831x_irq_sync_unlock,
.irq_disable = wm831x_irq_disable,
.irq_enable = wm831x_irq_enable,
.irq_set_type = wm831x_irq_set_type,
=======
.name = "wm831x",
.bus_lock = wm831x_irq_lock,
.bus_sync_unlock = wm831x_irq_sync_unlock,
.disable = wm831x_irq_disable,
.mask = wm831x_irq_mask,
.unmask = wm831x_irq_unmask,
.set_type = wm831x_irq_set_type,
.set_wake = wm831x_irq_set_wake,
>>>>>>> parent of 15f7fab... temp revert rk change
.irq_set_wake = wm831x_irq_set_wake,
};
#if WM831X_IRQ_LIST
@@ -558,18 +530,6 @@ static void wm831x_irq_worker(struct work_struct *work)
mutex_lock(&wm831x->irq_lock);
/* The touch interrupts are visible in the primary register as
* an optimisation; open code this to avoid complicating the
* main handling loop and so we can also skip iterating the
* descriptors.
*/
if (primary & WM831X_TCHPD_INT)
handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHPD);
if (primary & WM831X_TCHDATA_INT)
handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHDATA);
if (primary & (WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT))
goto out;
for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {
int offset = wm831x_irqs[i].reg - 1;
@@ -630,9 +590,6 @@ out_lock:
mutex_unlock(&wm831x->irq_lock);
out:
/* Touchscreen interrupts are handled specially in the driver */
status_regs[0] &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT);
for (i = 0; i < ARRAY_SIZE(status_regs); i++) {
if (status_regs[i])
wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i,
@@ -695,33 +652,18 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
0xffff);
}
if (!irq) {
dev_warn(wm831x->dev,
"No interrupt specified - functionality limited\n");
return 0;
}
if (!pdata || !pdata->irq_base) {
dev_err(wm831x->dev,
"No interrupt base specified, no interrupts\n");
return 0;
}
<<<<<<< HEAD
if (pdata->irq_cmos)
i = 0;
else
i = WM831X_IRQ_OD;
wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,
WM831X_IRQ_OD, i);
/* Try to flag /IRQ as a wake source; there are a number of
* unconditional wake sources in the PMIC so this isn't
* conditional but we don't actually care *too* much if it
* fails.
*/
ret = enable_irq_wake(irq);
if (ret != 0) {
dev_warn(wm831x->dev, "Can't enable IRQ as wake source: %d\n",
ret);
}
=======
wm831x->irq_wq = create_singlethread_workqueue("wm831x-irq");
if (!wm831x->irq_wq) {
dev_err(wm831x->dev, "Failed to allocate IRQ worker\n");
@@ -729,7 +671,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
}
>>>>>>> parent of 15f7fab... temp revert rk change
wm831x->irq = irq;
wm831x->flag_suspend = 0;
wm831x->irq_base = pdata->irq_base;
@@ -737,7 +678,7 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
wake_lock_init(&wm831x->irq_wake, WAKE_LOCK_SUSPEND, "wm831x_irq_wake");
wake_lock_init(&wm831x->handle_wake, WAKE_LOCK_SUSPEND, "wm831x_handle_wake");
#if WM831X_IRQ_LIST
wm831x->handle_wq = create_rt_workqueue("wm831x_handle_wq");
wm831x->handle_wq = create_workqueue("wm831x_handle_wq");
if (!wm831x->handle_wq) {
printk("cannot create workqueue\n");
return -EBUSY;
@@ -764,25 +705,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
irq_set_noprobe(cur_irq);
#endif
}
<<<<<<< HEAD
if (irq) {
ret = request_threaded_irq(irq, NULL, wm831x_irq_thread,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"wm831x", wm831x);
if (ret != 0) {
dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n",
irq, ret);
return ret;
}
} else {
dev_warn(wm831x->dev,
"No interrupt specified - functionality limited\n");
}
=======
#if (WM831X_IRQ_TYPE == IRQF_TRIGGER_LOW)
ret = request_threaded_irq(wm831x->irq, wm831x_irq_thread, NULL,
IRQF_TRIGGER_LOW| IRQF_ONESHOT,//IRQF_TRIGGER_FALLING, //
@@ -799,7 +721,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
}
enable_irq_wake(wm831x->irq); // so wm831x irq can wake up system
>>>>>>> parent of 15f7fab... temp revert rk change
/* Enable top level interrupts, we mask at secondary level */
wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);

70
drivers/mfd/wm831x-spi.c Normal file → Executable file
View File

@@ -14,10 +14,10 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <linux/mfd/wm831x/core.h>
static int wm831x_spi_read_device(struct wm831x *wm831x, unsigned short reg,
@@ -29,24 +29,14 @@ static int wm831x_spi_read_device(struct wm831x *wm831x, unsigned short reg,
/* Go register at a time */
for (r = reg; r < reg + (bytes / 2); r++) {
<<<<<<< HEAD
tx_val = r | 0x8000;
=======
tx_val = cpu_to_be16(r | 0x8000);
//printk("read:reg=0x%x,",reg);
>>>>>>> parent of 15f7fab... temp revert rk change
ret = spi_write_then_read(wm831x->control_data,
(u8 *)&tx_val, 2, (u8 *)d, 2);
if (ret != 0)
return ret;
<<<<<<< HEAD
*d = be16_to_cpu(*d);
=======
//printk("rec=0x%x\n",be16_to_cpu(*d));
//*d = be16_to_cpu(*d);
>>>>>>> parent of 15f7fab... temp revert rk change
d++;
}
@@ -64,15 +54,9 @@ static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
/* Go register at a time */
for (r = reg; r < reg + (bytes / 2); r++) {
<<<<<<< HEAD
data[0] = r;
data[1] = *s++;
=======
data[0] = cpu_to_be16(r);
data[1] = *s++;
//printk("write:reg=0x%x,send=0x%x\n",reg, data[0]);
>>>>>>> parent of 15f7fab... temp revert rk change
ret = spi_write(spi, (char *)&data, sizeof(data));
if (ret != 0)
return ret;
@@ -85,12 +69,8 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
{
struct wm831x *wm831x;
enum wm831x_parent type;
<<<<<<< HEAD
=======
int ret,gpio,irq;
>>>>>>> parent of 15f7fab... temp revert rk change
/* Currently SPI support for ID tables is unmerged, we're faking it */
if (strcmp(spi->modalias, "wm8310") == 0)
type = WM8310;
@@ -104,8 +84,6 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
type = WM8321;
else if (strcmp(spi->modalias, "wm8325") == 0)
type = WM8325;
else if (strcmp(spi->modalias, "wm8326") == 0)
type = WM8326;
else {
dev_err(&spi->dev, "Unknown device type\n");
return -EINVAL;
@@ -118,8 +96,6 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
spi->bits_per_word = 16;
spi->mode = SPI_MODE_0;
<<<<<<< HEAD
=======
gpio = spi->irq;
ret = gpio_request(gpio, "wm831x");
if (ret) {
@@ -133,18 +109,13 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
}
irq = gpio_to_irq(gpio);
>>>>>>> parent of 15f7fab... temp revert rk change
dev_set_drvdata(&spi->dev, wm831x);
wm831x->dev = &spi->dev;
wm831x->control_data = spi;
wm831x->read_dev = wm831x_spi_read_device;
wm831x->write_dev = wm831x_spi_write_device;
<<<<<<< HEAD
return wm831x_device_init(wm831x, type, spi->irq);
=======
return wm831x_device_init(wm831x, type, irq);
>>>>>>> parent of 15f7fab... temp revert rk change
}
static int __devexit wm831x_spi_remove(struct spi_device *spi)
@@ -156,31 +127,24 @@ static int __devexit wm831x_spi_remove(struct spi_device *spi)
return 0;
}
static int wm831x_spi_suspend(struct device *dev)
static int wm831x_spi_suspend(struct spi_device *spi, pm_message_t m)
{
struct wm831x *wm831x = dev_get_drvdata(dev);
struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
spin_lock(&wm831x->flag_lock);
wm831x->flag_suspend = 1;
spin_unlock(&wm831x->flag_lock);
return wm831x_device_suspend(wm831x);
}
static const struct dev_pm_ops wm831x_spi_pm = {
.freeze = wm831x_spi_suspend,
.suspend = wm831x_spi_suspend,
};
static struct spi_driver wm8310_spi_driver = {
.driver = {
.name = "wm8310",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
.pm = &wm831x_spi_pm,
},
.probe = wm831x_spi_probe,
.remove = __devexit_p(wm831x_spi_remove),
.suspend = wm831x_spi_suspend,
};
static struct spi_driver wm8311_spi_driver = {
@@ -188,10 +152,10 @@ static struct spi_driver wm8311_spi_driver = {
.name = "wm8311",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
.pm = &wm831x_spi_pm,
},
.probe = wm831x_spi_probe,
.remove = __devexit_p(wm831x_spi_remove),
.suspend = wm831x_spi_suspend,
};
static struct spi_driver wm8312_spi_driver = {
@@ -199,10 +163,10 @@ static struct spi_driver wm8312_spi_driver = {
.name = "wm8312",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
.pm = &wm831x_spi_pm,
},
.probe = wm831x_spi_probe,
.remove = __devexit_p(wm831x_spi_remove),
.suspend = wm831x_spi_suspend,
};
static struct spi_driver wm8320_spi_driver = {
@@ -210,10 +174,10 @@ static struct spi_driver wm8320_spi_driver = {
.name = "wm8320",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
.pm = &wm831x_spi_pm,
},
.probe = wm831x_spi_probe,
.remove = __devexit_p(wm831x_spi_remove),
.suspend = wm831x_spi_suspend,
};
static struct spi_driver wm8321_spi_driver = {
@@ -221,10 +185,10 @@ static struct spi_driver wm8321_spi_driver = {
.name = "wm8321",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
.pm = &wm831x_spi_pm,
},
.probe = wm831x_spi_probe,
.remove = __devexit_p(wm831x_spi_remove),
.suspend = wm831x_spi_suspend,
};
static struct spi_driver wm8325_spi_driver = {
@@ -232,21 +196,10 @@ static struct spi_driver wm8325_spi_driver = {
.name = "wm8325",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
.pm = &wm831x_spi_pm,
},
.probe = wm831x_spi_probe,
.remove = __devexit_p(wm831x_spi_remove),
};
static struct spi_driver wm8326_spi_driver = {
.driver = {
.name = "wm8326",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
.pm = &wm831x_spi_pm,
},
.probe = wm831x_spi_probe,
.remove = __devexit_p(wm831x_spi_remove),
.suspend = wm831x_spi_suspend,
};
static int __init wm831x_spi_init(void)
@@ -277,17 +230,12 @@ static int __init wm831x_spi_init(void)
if (ret != 0)
pr_err("Failed to register WM8325 SPI driver: %d\n", ret);
ret = spi_register_driver(&wm8326_spi_driver);
if (ret != 0)
pr_err("Failed to register WM8326 SPI driver: %d\n", ret);
return 0;
}
subsys_initcall(wm831x_spi_init);
static void __exit wm831x_spi_exit(void)
{
spi_unregister_driver(&wm8326_spi_driver);
spi_unregister_driver(&wm8325_spi_driver);
spi_unregister_driver(&wm8321_spi_driver);
spi_unregister_driver(&wm8320_spi_driver);

View File

@@ -651,7 +651,7 @@ static UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume,
static struct i2c_driver wm8994_i2c_driver = {
.driver = {
.name = "wm8994",
.name = "WM8994",
.owner = THIS_MODULE,
.pm = &wm8994_pm_ops,
},

View File

@@ -540,7 +540,8 @@ config STE
config MTK23D
bool "MTK6223D modem control driver"
default n
config FM580X
bool "FM rda580x driver"
@@ -553,6 +554,15 @@ config MW100
config RK29_NEWTON
bool "RK29_NEWTON misc driver"
config RK29_SC8800
bool "SC8800 misc driver"
default n
config TDSC8800
bool "TDSC8800 modem control driver"
default n
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"

View File

@@ -61,3 +61,5 @@ obj-$(CONFIG_RK29_SUPPORT_MODEM) += rk29_modem/
obj-$(CONFIG_GPS_GNS7560) += gps/
obj-y += mpu3050/
obj-$(CONFIG_RK29_NEWTON) += newton.o
obj-$(CONFIG_TDSC8800) += tdsc8800.o
obj-$(CONFIG_RK29_SC8800) += sc8800.o

View File

@@ -248,7 +248,7 @@ static struct file_operations rk29_gps_fops = {
.owner = THIS_MODULE,
.open = rk29_gps_open,
.read = rk29_gps_read,
.ioctl = rk29_gps_ioctl,
.unlocked_ioctl = rk29_gps_ioctl,
.release = rk29_gps_release,
};
@@ -272,8 +272,8 @@ static int rk29_gps_probe(struct platform_device *pdev)
return ret;
}
init_MUTEX(&pdata->power_sem);
pdata->wq = create_freezeable_workqueue("rk29_gps");
sema_init(&pdata->power_sem,1);
pdata->wq = create_freezable_workqueue("rk29_gps");
INIT_WORK(&pdata->work, rk29_gps_delay_power_downup);
pdata->power_flag = 0;

View File

@@ -23,6 +23,7 @@
#include <linux/mtk23d.h>
#include <linux/wakelock.h>
#include "../mtd/rknand/api_flash.h"
#include <linux/slab.h>
MODULE_LICENSE("GPL");
@@ -290,9 +291,9 @@ int modem_poweron_off(int on_off)
static int power_on =1;
static int mtk23d_open(struct inode *inode, struct file *file)
{
struct rk2818_23d_data *pdata = gpdata;
//struct rk2818_23d_data *pdata = gpdata;
//struct rk2818_23d_data *pdata = gpdata = pdev->dev.platform_data;
struct platform_data *pdev = container_of(pdata, struct device, platform_data);
//struct platform_data *pdev = container_of(pdata, struct device, platform_data);
MODEMDBG("modem_open\n");
@@ -302,7 +303,7 @@ static int mtk23d_open(struct inode *inode, struct file *file)
power_on = 0;
modem_poweron_off(1);
}
device_init_wakeup(&pdev, 1);
device_init_wakeup(&pdev->dev, 1);
return 0;
}
@@ -405,7 +406,7 @@ static struct file_operations mtk23d_fops = {
.owner = THIS_MODULE,
.open = mtk23d_open,
.release = mtk23d_release,
.ioctl = mtk23d_ioctl
.unlocked_ioctl = mtk23d_ioctl
};
static struct miscdevice mtk23d_misc = {
@@ -423,6 +424,7 @@ static int mtk23d_probe(struct platform_device *pdev)
MODEMDBG("mtk23d_probe\n");
//pdata->io_init();
pdata->dev = &pdev->dev;
mt6223d_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
if(NULL == mt6223d_data)
@@ -492,7 +494,7 @@ static int mtk23d_probe(struct platform_device *pdev)
#endif
INIT_WORK(&mt6223d_data->work, bpwakeup_work_func_work);
init_MUTEX(&pdata->power_sem);
sema_init(&pdata->power_sem,1);
power_on = 1;
result = misc_register(&mtk23d_misc);
if(result)

728
drivers/misc/sc8800.c Executable file
View File

@@ -0,0 +1,728 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/wait.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/rwsem.h>
#include <mach/gpio.h>
#include <mach/iomux.h>
#include <mach/board.h>
#include <linux/wakelock.h>
#if 0
#define sc8800_dbg(dev, format, arg...) \
dev_printk(KERN_INFO , dev , format , ## arg)
//#define SC8800_PRINT_BUF
#else
#define sc8800_dbg(dev, format, arg...)
#endif
#define READ_TIMEOUT 30000 //no use
#define WRITE_TIMEOUT 80 //80ms
#define RD_BUF_SIZE (16*PAGE_SIZE) // 64K
#define WR_BUF_SIZE (2*PAGE_SIZE) // __get_free_pages(GFP_KERNEL, 1) ==> pages = 2^1 = 2
#define MAX_RX_LIST 256
#define BP_PACKET_SIZE 64
#define BP_PACKET_HEAD_LEN 16
#define BP_PACKET_DATA_LEN 48
struct plat_sc8800 {
int slav_rts_pin;
int slav_rdy_pin;
int master_rts_pin;
int master_rdy_pin;
int poll_time;
};
struct bp_head{
u16 tag; //0x7e7f
u16 type; //0xaa55
u32 length; //the length of data after head(8192-128 bytes)
u32 fram_num; //no used , always 0
u32 reserved; ////reserved
char data[BP_PACKET_DATA_LEN];
};
struct sc8800_data {
struct device *dev;
struct spi_device *spi;
struct workqueue_struct *rx_wq;
struct workqueue_struct *tx_wq;
struct work_struct rx_work;
struct work_struct tx_work;
struct wake_lock rx_wake;
struct wake_lock tx_wake;
wait_queue_head_t waitrq;
wait_queue_head_t waitwq;
spinlock_t lock;
int irq;
int slav_rts;
int slav_rdy;
int master_rts;
int master_rdy;
int write_finished;
int write_tmo;
char *rx_buf;
int rx_len;
char *tx_buf;
int tx_len;
int rw_enable;
int is_suspend;
};
static DEFINE_MUTEX(sc8800s_lock);
static DECLARE_RWSEM(sc8800_rsem);
static DECLARE_RWSEM(sc8800_wsem);
struct sc8800_data *g_sc8800 = NULL;
char tmp_buf[1024];
static int bp_rts(struct sc8800_data *sc8800)
{
return gpio_get_value(sc8800->slav_rts);
}
static int bp_rdy(struct sc8800_data *sc8800)
{
return gpio_get_value(sc8800->slav_rdy);
}
static void ap_rts(struct sc8800_data *sc8800, int value)
{
gpio_set_value(sc8800->master_rts, value);
}
static void ap_rdy(struct sc8800_data *sc8800, int value)
{
gpio_set_value(sc8800->master_rdy, value);
}
static void sc8800_print_buf(struct sc8800_data *sc8800, char *buf, const char *func, int len)
{
#ifdef SC8800_PRINT_BUF
int i;
char *tmp = NULL;
tmp = kzalloc(len*7, GFP_KERNEL);
sc8800_dbg(sc8800->dev, "%s buf[%d] = :\n", func, len);
for(i = 0; i < len; i++){
if(i % 16 == 0 && i != 0)
sprintf(tmp, "%s\n", tmp);
sprintf(tmp, "%s[0x%2x] ", tmp, buf[i]);
}
printk("%s\n", tmp);
kfree(tmp);
#endif
return;
}
static void buf_swp(char *buf, int len)
{
int i;
char temp;
len = (len/2)*2;
for(i = 0; i < len; i += 2)
{
temp = buf[i];
buf[i] = buf[i+1];
buf[i+1] = temp;
}
}
static void spi_in(struct sc8800_data *sc8800, char *tx_buf, unsigned len, int* err)
{
struct spi_message message;
struct spi_transfer tran;
buf_swp(tx_buf, len);
tran.tx_buf = (void *)tx_buf;
tran.rx_buf = tmp_buf;
tran.len = len;
tran.speed_hz = 0;
tran.bits_per_word = 16;
spi_message_init(&message);
spi_message_add_tail(&tran, &message);
*err = spi_sync(sc8800->spi, &message);
sc8800_print_buf(sc8800, tx_buf, __func__, len);
}
static void spi_out(struct sc8800_data *sc8800, char *rx_buf, unsigned len, int* err)
{
struct spi_message message;
struct spi_transfer tran;
memset(rx_buf, 0, len);
tran.tx_buf = tmp_buf;
tran.rx_buf = (void *)rx_buf;
tran.len = len;
tran.speed_hz = 0;
tran.bits_per_word = 16;
spi_message_init(&message);
spi_message_add_tail(&tran, &message);
*err = spi_sync(sc8800->spi, &message);
sc8800_print_buf(sc8800, rx_buf, __func__, len);
buf_swp(rx_buf, len);
}
static int ap_get_head(struct sc8800_data *sc8800, struct bp_head *packet)
{
int err = 0, count = 5;
char buf[BP_PACKET_SIZE];
retry:
spi_out(sc8800, buf, BP_PACKET_SIZE, &err);
if(err < 0 && count > 0)
{
dev_warn(sc8800->dev, "%s spi_out return error, retry count = %d\n",
__func__, count);
count--;
mdelay(10);
goto retry;
}
if(err < 0)
return err;
memcpy((char *)(packet), buf, BP_PACKET_SIZE);
sc8800_dbg(sc8800->dev, "%s tag = 0x%4x, type = 0x%4x, length = %x\n",
__func__, packet->tag, packet->type, packet->length);
if ((packet->tag != 0x7e7f) || (packet->type != 0xaa55))
return -1;
else
return 0;
}
static int sc8800_rx(struct sc8800_data *sc8800)
{
int ret = 0, len, real_len;
struct bp_head packet;
char *buf = NULL;
ap_rdy(sc8800,0);
ret = ap_get_head(sc8800, &packet);
if(ret < 0){
dev_err(sc8800->dev, "ERR: %s ap_get_head err = %d\n", __func__, ret);
goto out;
}
len = packet.length;
if(len > BP_PACKET_DATA_LEN)
real_len = (((len -BP_PACKET_DATA_LEN-1)/BP_PACKET_SIZE)+2)*BP_PACKET_SIZE;
else
real_len = BP_PACKET_SIZE;
if(len > RD_BUF_SIZE){
dev_err(sc8800->dev, "ERR: %s len[%d] is large than buffer size[%lu]\n",
__func__, real_len, RD_BUF_SIZE);
goto out;
}
buf = kzalloc(real_len, GFP_KERNEL);
if(!buf){
dev_err(sc8800->dev,"ERR: %s no memmory for rx_buf\n", __func__);
goto out;
}
memcpy(buf, packet.data, BP_PACKET_DATA_LEN);
if(len > BP_PACKET_DATA_LEN)
spi_out(sc8800, buf + BP_PACKET_DATA_LEN, real_len-BP_PACKET_SIZE, &ret);
if(ret < 0){
dev_err(sc8800->dev, "ERR: %s spi out err = %d\n", __func__, ret);
goto out;
}
spin_lock(&sc8800->lock);
if(sc8800->rx_len + len > RD_BUF_SIZE){
dev_warn(sc8800->dev, "WARN: %s read buffer is full\n", __func__);
}else
{
memcpy(sc8800->rx_buf+sc8800->rx_len, buf, len);
sc8800->rx_len += len;
}
spin_unlock(&sc8800->lock);
sc8800_dbg(sc8800->dev, "%s rx_len = %d\n", __func__, sc8800->rx_len);
ret = sc8800->rx_len;
out:
ap_rdy(sc8800,1);
if(buf)
kfree(buf);
buf = NULL;
return ret;
}
static int sc8800_data_packet(char *dst, char *src, int src_len)
{
int dst_len = 0;
struct bp_head packet;
if(src_len > BP_PACKET_DATA_LEN)
dst_len = (((src_len -BP_PACKET_DATA_LEN-1)/BP_PACKET_SIZE)+2)*BP_PACKET_SIZE;
else
dst_len = BP_PACKET_SIZE;
packet.tag =0x7e7f;
packet.type = 0xaa55;
packet.length = src_len;
packet.fram_num = 0;
packet.reserved = 0;
memcpy(packet.data, src, BP_PACKET_DATA_LEN);
memcpy(dst, (char *)&packet, BP_PACKET_SIZE);
if(src_len >= BP_PACKET_DATA_LEN)
memcpy(dst+BP_PACKET_SIZE, src+BP_PACKET_DATA_LEN, src_len - BP_PACKET_DATA_LEN);
return dst_len;
}
static int sc8800_tx(struct sc8800_data *sc8800)
{
int ret = 0, len;
char *buf = NULL;
sc8800->write_tmo = 0;
buf = kzalloc(WR_BUF_SIZE + BP_PACKET_SIZE, GFP_KERNEL);
if(!buf){
dev_err(sc8800->dev, "ERR: no memery for buf\n");
return -ENOMEM;
}
while(!bp_rts(sc8800)){
if(sc8800->write_tmo){
sc8800_dbg(sc8800->dev, "bp_rts = 0\n");
kfree(buf);
return -1;
}
schedule();
}
mutex_lock(&sc8800s_lock);
ap_rts(sc8800,0);
#if 1
while(bp_rdy(sc8800)){
if(sc8800->write_tmo){
ap_rts(sc8800,1);
sc8800_dbg(sc8800->dev, "ERR: %s write timeout ->bp not ready (bp_rdy = 1)\n", __func__);
kfree(buf);
mutex_unlock(&sc8800s_lock);
return -1;
}
schedule();
}
#endif
len = sc8800_data_packet(buf, sc8800->tx_buf, sc8800->tx_len);
spi_in(sc8800, buf, len, &ret);
if(ret < 0)
dev_err(sc8800->dev, "ERR: %s spi in err = %d\n", __func__, ret);
ap_rts(sc8800,1);
if(buf){
kfree(buf);
buf = NULL;
}
mutex_unlock(&sc8800s_lock);
#if 1
while(!bp_rdy(sc8800)){
if(sc8800->write_tmo){
dev_err(sc8800->dev, "ERR: %s write timeout -> bp receiving (bp_rdy = 0)\n", __func__);
ret = -1;
}
schedule();
}
#endif
return ret;
}
static irqreturn_t sc8800_irq(int irq, void *dev_id)
{
struct sc8800_data *sc8800 = (struct sc8800_data *)dev_id;
sc8800_dbg(sc8800->dev, "%s\n", __func__);
#if 0
if(sc8800->is_suspend)
rk28_send_wakeup_key();
#endif
wake_lock(&sc8800->rx_wake);
queue_work(sc8800->rx_wq, &sc8800->rx_work);
return IRQ_HANDLED;
}
static void sc8800_rx_work(struct work_struct *rx_work)
{
struct sc8800_data *sc8800 = container_of(rx_work, struct sc8800_data, rx_work);
sc8800_dbg(sc8800->dev, "%s\n", __func__);
mutex_lock(&sc8800s_lock);
sc8800->rx_len = sc8800_rx(sc8800);
wake_unlock(&sc8800->rx_wake);
if(sc8800->rx_len <= 0)
sc8800->rx_len = 0;
wake_up(&sc8800->waitrq);
mutex_unlock(&sc8800s_lock);
}
static void sc8800_tx_work(struct work_struct *tx_work)
{
struct sc8800_data *sc8800 = container_of(tx_work, struct sc8800_data, tx_work);
sc8800_dbg(sc8800->dev, "%s bp_rts = %d\n", __func__, bp_rts(sc8800));
wake_lock(&sc8800->tx_wake);
if(sc8800_tx(sc8800) == 0){
sc8800->write_finished = 1;
wake_up(&sc8800->waitwq);
}
wake_unlock(&sc8800->tx_wake);
}
static ssize_t sc8800_read(struct file *file,
char __user *buf, size_t count, loff_t *offset)
{
int ret = 0;
ssize_t size = 0;
struct sc8800_data *sc8800 = (struct sc8800_data *)file->private_data;
sc8800_dbg(sc8800->dev, "%s count = %d\n", __func__, count);
if(!buf){
dev_err(sc8800->dev, "ERR: %s user_buf = NULL\n", __func__);
return -EFAULT;
}
down_write(&sc8800_rsem);
if(!(file->f_flags & O_NONBLOCK)){
ret = wait_event_interruptible(sc8800->waitrq, (sc8800->rx_len > 0 || (sc8800->rw_enable <= 0)));
if (ret) {
up_write(&sc8800_rsem);
return ret;
}
}
if(sc8800->rw_enable <= 0){
dev_err(sc8800->dev, "ERR: %s sc8800 is released\n", __func__);
up_write(&sc8800_rsem);
return -EFAULT;
}
if(sc8800->rx_len == 0){
dev_warn(sc8800->dev, "WARN: %s nonblock read, rx_len = 0\n", __func__);
return 0;
}
spin_lock(&sc8800->lock);
sc8800_print_buf(sc8800, sc8800->rx_buf, __func__, sc8800->rx_len);
if(sc8800->rx_len > count){
size = count;
ret = copy_to_user(buf, sc8800->rx_buf, count);
}else{
size = sc8800->rx_len;
ret = copy_to_user(buf, sc8800->rx_buf, sc8800->rx_len);
}
if(ret < 0){
dev_err(sc8800->dev, "ERR: %s copy to user ret = %d\n", __func__, ret);
spin_unlock(&sc8800->lock);
up_write(&sc8800_rsem);
return -EFAULT;
}
if(sc8800->rx_len > count)
memmove(sc8800->rx_buf, sc8800->rx_buf + count, sc8800->rx_len - count);
sc8800->rx_len -= size;
spin_unlock(&sc8800->lock);
up_write(&sc8800_rsem);
return size;
}
static ssize_t sc8800_write(struct file *file,
const char __user *buf, size_t count, loff_t *offset)
{
int ret = 0;
struct sc8800_data *sc8800 = (struct sc8800_data *)file->private_data;
sc8800_dbg(sc8800->dev, "%s count = %d\n", __func__, count);
if(count > WR_BUF_SIZE){
dev_err(sc8800->dev, "ERR: %s count[%u] > WR_BUF_SIZE[%lu]\n",
__func__, count, WR_BUF_SIZE);
return -EFAULT;
}
down_write(&sc8800_wsem);
sc8800_print_buf(sc8800, sc8800->tx_buf, __func__, count);
memset(sc8800->tx_buf, 0, WR_BUF_SIZE);
ret = copy_from_user(sc8800->tx_buf, buf, count);
if(ret < 0){
dev_err(sc8800->dev, "ERR: %s copy from user ret = %d\n", __func__, ret);
up_write(&sc8800_wsem);
return -EFAULT;
}
sc8800->write_finished = 0;
sc8800->tx_len = count;
queue_work(sc8800->tx_wq, &sc8800->tx_work);
ret = wait_event_timeout(sc8800->waitwq,
(sc8800->write_finished || sc8800->rw_enable <= 0),
msecs_to_jiffies(WRITE_TIMEOUT));
if(sc8800->rw_enable <= 0){
dev_err(sc8800->dev, "ERR: %ssc8800 is released\n", __func__);
up_write(&sc8800_wsem);
return -EFAULT;
}
if(ret == 0){
sc8800->write_tmo = 1;
dev_err(sc8800->dev, "ERR: %swrite timeout\n", __func__);
up_write(&sc8800_wsem);
return -ETIMEDOUT;
//return count;
}else{
up_write(&sc8800_wsem);
return count;
}
}
static int sc8800_open(struct inode *inode, struct file *file)
{
file->private_data = g_sc8800;
sc8800_dbg(g_sc8800->dev, "%s\n", __func__);
g_sc8800->write_finished = 0;
g_sc8800->write_tmo = 0;
g_sc8800->rw_enable++;
return 0;
}
static int sc8800_release(struct inode *inode, struct file *file)
{
struct sc8800_data *sc8800 = (struct sc8800_data *)file->private_data;
sc8800_dbg(sc8800->dev, "%s\n", __func__);
if(sc8800->rw_enable > 0)
sc8800->rw_enable--;
wake_up(&sc8800->waitrq);
wake_up(&sc8800->waitwq);
return 0;
}
static const struct file_operations sc8800_fops = {
.open = sc8800_open,
.release = sc8800_release,
.read = sc8800_read,
.write = sc8800_write,
};
static struct miscdevice sc8800_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "sc8800",
.fops = &sc8800_fops,
};
static int __devinit sc8800_probe(struct spi_device *spi)
{
int ret = 0;
unsigned long page;
struct sc8800_data *sc8800 = NULL;
struct plat_sc8800 *pdata = NULL;
pdata = spi->dev.platform_data;
if (!pdata) {
dev_err(&spi->dev, "ERR: spi data missing\n");
return -ENODEV;
}
sc8800 = (struct sc8800_data *)kzalloc(sizeof(struct sc8800_data), GFP_KERNEL);
if(!sc8800){
dev_err(&spi->dev, "ERR: no memory for sc8800\n");
return -ENOMEM;
}
g_sc8800 = sc8800;
page = __get_free_pages(GFP_KERNEL, 4); //2^4 * 4K = 64K
if(!page){
dev_err(&spi->dev, "ERR: no memory for rx_buf\n");
ret = -ENOMEM;
goto err_get_free_page1;
}
sc8800->rx_buf = (char *)page;
page = __get_free_pages(GFP_KERNEL, 1);//2^1 * 4K = 8K
if(!page){
dev_err(&spi->dev, "ERR: no memory for tx_buf\n");
ret = -ENOMEM;
goto err_get_free_page2;
}
sc8800->tx_buf = (char *)page;
sc8800->spi = spi;
sc8800->dev = &spi->dev;
dev_set_drvdata(sc8800->dev, sc8800);
spi->bits_per_word = 16;
spi->mode = SPI_MODE_2;
spi->max_speed_hz = 1000*1000*8;
ret = spi_setup(spi);
if (ret < 0){
dev_err(sc8800->dev, "ERR: fail to setup spi\n");
goto err_spi_setup;
}
sc8800->irq = gpio_to_irq(pdata->slav_rts_pin);
sc8800->slav_rts = pdata->slav_rts_pin;
sc8800->slav_rdy = pdata->slav_rdy_pin;
sc8800->master_rts = pdata->master_rts_pin;
sc8800->master_rdy = pdata->master_rdy_pin;
rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1);
rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_GPIO1C0);
ret = gpio_request(sc8800->slav_rts, "salv_rts");
if(ret < 0){
dev_err(sc8800->dev, "ERR: gpio request slav_rts[%d]\n", sc8800->slav_rts);
goto err_gpio_request_slav_rts;
}
ret = gpio_request(sc8800->slav_rdy, "slav_rdy");
if(ret < 0){
dev_err(sc8800->dev, "ERR: gpio request slav_rdy\n");
goto err_gpio_request_slav_rdy;
}
ret = gpio_request(sc8800->master_rts, "master_rts");
if(ret < 0){
dev_err(sc8800->dev, "ERR: gpio request master_rts\n");
goto err_gpio_request_master_rts;
}
ret = gpio_request(sc8800->master_rdy, "master_rdy");
if(ret < 0){
dev_err(sc8800->dev, "ERR: gpio request master_rdy\n");
goto err_gpio_request_master_rdy;
}
gpio_direction_input(sc8800->slav_rts);
gpio_pull_updown(sc8800->slav_rts, GPIOPullUp);
gpio_direction_input(sc8800->slav_rdy);
gpio_pull_updown(sc8800->slav_rdy, GPIOPullUp);
gpio_direction_output(sc8800->master_rts, GPIO_HIGH);
gpio_direction_output(sc8800->master_rdy, GPIO_HIGH);
init_waitqueue_head(&sc8800->waitrq);
init_waitqueue_head(&sc8800->waitwq);
spin_lock_init(&sc8800->lock);
ret = misc_register(&sc8800_device);
if(ret < 0){
dev_err(sc8800->dev, "ERR: fail to register misc device\n");
goto err_misc_register;
}
ret = request_irq(sc8800->irq, sc8800_irq, IRQF_TRIGGER_FALLING, "sc8800", sc8800);
if(ret < 0){
dev_err(sc8800->dev, "ERR: fail to request irq %d\n", sc8800->irq);
goto err_request_irq;
}
wake_lock_init(&sc8800->rx_wake, WAKE_LOCK_SUSPEND, "sc8800_rx_wake");
wake_lock_init(&sc8800->tx_wake, WAKE_LOCK_SUSPEND, "sc8800_tx_wake");
enable_irq_wake(sc8800->irq);
sc8800->rx_wq = create_workqueue("sc8800_rxwq");
sc8800->tx_wq = create_workqueue("sc8800_txwq");
INIT_WORK(&sc8800->rx_work, sc8800_rx_work);
INIT_WORK(&sc8800->tx_work, sc8800_tx_work);
dev_info(sc8800->dev, "sc8800 probe ok\n");
return 0;
err_request_irq:
gpio_free(sc8800->master_rdy);
err_misc_register:
misc_deregister(&sc8800_device);
err_gpio_request_master_rdy:
gpio_free(sc8800->master_rts);
err_gpio_request_master_rts:
gpio_free(sc8800->slav_rdy);
err_gpio_request_slav_rdy:
gpio_free(sc8800->slav_rts);
err_gpio_request_slav_rts:
err_spi_setup:
free_page((unsigned long)sc8800->tx_buf);
err_get_free_page2:
free_page((unsigned long)sc8800->rx_buf);
err_get_free_page1:
kfree(sc8800);
sc8800 = NULL;
g_sc8800 = NULL;
return ret;
}
static int __devexit sc8800_remove(struct spi_device *spi)
{
struct sc8800_data *sc8800 = dev_get_drvdata(&spi->dev);
destroy_workqueue(sc8800->rx_wq);
destroy_workqueue(sc8800->tx_wq);
free_irq(sc8800->irq, sc8800);
gpio_free(sc8800->master_rdy);
gpio_free(sc8800->master_rts);
gpio_free(sc8800->slav_rdy);
gpio_free(sc8800->slav_rts);
free_page((unsigned long)sc8800->tx_buf);
free_page((unsigned long)sc8800->rx_buf);
kfree(sc8800);
sc8800 = NULL;
return 0;
}
#ifdef CONFIG_PM
static int sc8800_suspend(struct spi_device *spi, pm_message_t state)
{
struct sc8800_data *sc8800 = dev_get_drvdata(&spi->dev);
sc8800->is_suspend = 1;
return 0;
}
static int sc8800_resume(struct spi_device *spi)
{
struct sc8800_data *sc8800 = dev_get_drvdata(&spi->dev);
sc8800->is_suspend = 0;
return 0;
}
#else
#define sc8800_suspend NULL
#define sc8800_resume NULL
#endif
static struct spi_driver sc8800_driver = {
.driver = {
.name = "sc8800",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = sc8800_probe,
.remove = __devexit_p(sc8800_remove),
.suspend = sc8800_suspend,
.resume = sc8800_resume,
};
static int __init sc8800_init(void)
{
printk("sc8800_init\n");
return spi_register_driver(&sc8800_driver);
}
module_init(sc8800_init);
static void __exit sc8800_exit(void)
{
spi_unregister_driver(&sc8800_driver);
}
module_exit(sc8800_exit);
MODULE_DESCRIPTION("SC8800 driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("spi:SC8800");

179
drivers/misc/tdsc8800.c Executable file
View File

@@ -0,0 +1,179 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/circ_buf.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <mach/iomux.h>
#include <mach/gpio.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/mtk23d.h>
MODULE_LICENSE("GPL");
#define DEBUG
#ifdef DEBUG
#define MODEMDBG(x...) printk(x)
#else
#define MODEMDBG(fmt,argss...)
#endif
#define SLEEP 1
#define READY 0
struct rk2818_23d_data *gpdata = NULL;
int modem_poweron_off(int on_off)
{
struct rk2818_23d_data *pdata = gpdata;
if(on_off)
{
printk("tdsc8800_poweron\n");
gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW); // power on enable
}
else
{
printk("tdsc8800_poweroff\n");
gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
}
return 0;
}
static int tdsc8800_open(struct inode *inode, struct file *file)
{
modem_poweron_off(1);
device_init_wakeup(gpdata->dev, 1);
return 0;
}
static int tdsc8800_release(struct inode *inode, struct file *file)
{
MODEMDBG("tdsc8800_release\n");
return 0;
}
static long tdsc8800_ioctl(struct file *file, unsigned int a, unsigned long b)
{
return 0;
}
static struct file_operations tdsc8800_fops = {
.owner = THIS_MODULE,
.open =tdsc8800_open,
.release =tdsc8800_release,
.unlocked_ioctl = tdsc8800_ioctl
};
static struct miscdevice tdsc8800_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "tdsc8800",
.fops = &tdsc8800_fops
};
static int tdsc8800_probe(struct platform_device *pdev)
{
struct rk2818_23d_data *pdata = gpdata = pdev->dev.platform_data;
struct modem_dev *tdsc8800_data = NULL;
int result = 0;
MODEMDBG("tdsc8800_probe\n");
//pdata->io_init();
pdata->dev = &pdev->dev;
tdsc8800_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
if(NULL == tdsc8800_data)
{
printk("failed to request tdsc8800_data\n");
goto err6;
}
platform_set_drvdata(pdev, tdsc8800_data);
result = gpio_request(pdata->bp_power, "tdsc8800");
if (result) {
printk("failed to request BP_POW_EN gpio\n");
goto err1;
}
gpio_direction_output(pdata->bp_power, GPIO_LOW);
gpio_set_value(pdata->bp_power, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
result = misc_register(&tdsc8800_misc);
if(result)
{
MODEMDBG("misc_register err\n");
}
MODEMDBG("mtk23d_probe ok\n");
return result;
err1:
gpio_free(pdata->bp_power);
err6:
kfree(tdsc8800_data);
return result;
}
int tdsc8800_suspend(struct platform_device *pdev)
{
return 0;
}
int tdsc8800_resume(struct platform_device *pdev)
{
return 0;
}
void tdsc8800_shutdown(struct platform_device *pdev, pm_message_t state)
{
struct rk2818_23d_data *pdata = pdev->dev.platform_data;
struct modem_dev *mt6223d_data = platform_get_drvdata(pdev);
MODEMDBG("%s \n", __FUNCTION__);
modem_poweron_off(0); // power down
gpio_free(pdata->bp_power);
kfree(mt6223d_data);
}
static struct platform_driver tdsc8800_driver = {
.probe = tdsc8800_probe,
.shutdown = tdsc8800_shutdown,
.suspend = tdsc8800_suspend,
.resume = tdsc8800_resume,
.driver = {
.name = "tdsc8800",
.owner = THIS_MODULE,
},
};
static int __init tdsc8800_init(void)
{
int ret = platform_driver_register(&tdsc8800_driver);
MODEMDBG("tdsc8800_init ret=%d\n",ret);
return ret;
}
static void __exit tdsc8800_exit(void)
{
MODEMDBG("tdsc8800_exit\n");
platform_driver_unregister(&tdsc8800_driver);
}
module_init(tdsc8800_init);
module_exit(tdsc8800_exit);

View File

@@ -696,7 +696,7 @@ void rk29_sdmmc_set_frq(struct rk29_sdmmc *host)
card = (struct mmc_card *)mmchost->card;
ios = ( struct mmc_ios *)&mmchost->ios;
if(!card && !ios)
if(!card || !ios)
return;
if(MMC_POWER_ON == ios->power_mode)

View File

@@ -44,6 +44,16 @@ choice
A library for Broadcom BCM4329 SDIO WLAN/BT combo devices.
So far, the following modules have been verified:
(1) Samsung SWL-B23
config BCM4319
depends on WLAN_80211 && MMC
select WIRELESS_EXT
select WEXT_PRIV
select IEEE80211
select FW_LOADER
bool "Broadcom BCM4319 WiFi SDIO"
---help---
A library for Broadcom BCM4319 SDIO WLAN devices.
config MV8686
depends on WLAN_80211 && MMC
@@ -59,11 +69,8 @@ choice
(3) USI WM-G-MR-09
(4) Murata SP-8HEP-P
source "drivers/net/wireless/bcm4319/Kconfig"
source "drivers/net/wireless/rtl8192c/Kconfig"
endchoice
#source "drivers/net/wireless/bcm4329/Kconfig"
endif

View File

@@ -1,54 +0,0 @@
===========================================================================
=== Version 1.05 @ 2011-03-26 ===
===========================================================================
1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˯<EFBFBD><CBAF>15<31><35><EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2. <20><><EFBFBD><EFBFBD>Combo-SCAN<41><4E>֧<EFBFBD><D6A7>wpa_supplicant_6
===========================================================================
=== Version 1.04 @ 2011-03-21 ===
===========================================================================
1. <20><><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>AP<41><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
===========================================================================
=== Version 1.03 @ 2011-01-24 ===
===========================================================================
1. <20><><EFBFBD>Ӷ<EFBFBD>RK29ƽ̨<C6BD><CCA8>֧<EFBFBD>֡<EFBFBD>
===========================================================================
=== Version 1.02 @ 20101102 ===
===========================================================================
1. <20><>ɨ<EFBFBD><C9A8><EFBFBD>б<EFBFBD><D0B1>У<EFBFBD><D0A3><EFBFBD>һЩAP<41><50>ʹ<EFBFBD>Ͻ<EFBFBD><CFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
=><3E><>tplinklai<61><69>Ϊͨ<CEAA><CDA8>13<31><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
=><3E><><EFBFBD>ֵ<EFBFBD>ǰ<EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD>ģʽ<C4A3>У<EFBFBD>ֻ֧<D6BB><D6A7>ɨ<EFBFBD>赽ͨ<E8B5BD><CDA8>11<31><31>
=>dhd_preinit_ioctls<6C><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>º<EFBFBD><C2BA><EFBFBD><EFBFBD><EFBFBD>
dhdcdc_query_ioctl(dhd, 0, WLC_GET_COUNTRY,
dhd->country_code, sizeof(dhd->country_code));
<20><><EFBFBD><EFBFBD>Ŀǰģ<C7B0><C4A3>Ĭ<EFBFBD>ϵ<EFBFBD>COUNTRY CODE<44><45>US<55><53><EFBFBD><EFBFBD>US<55><53><EFBFBD><EFBFBD>ֻ֧<D6BB><D6A7>11<31><31>ͨ<EFBFBD><CDA8><EFBFBD>ġ<EFBFBD>
=>
===========================================================================
=== Version 1.01 @ 20101027 ===
===========================================================================
1. <20><>Ϊʹ<CEAA><CAB9>wifi_version.h<>еİ汾<C4B0><E6B1BE><EFBFBD>
2. ͨ<><CDA8><EFBFBD>ڰ<EFBFBD><DAB0><EFBFBD>netperf -H 192.168.1.200 -t TCP_STREAM<41><4D><EFBFBD>в<EFBFBD><D0B2>ԣ<EFBFBD><D4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD>
[204] dhd_bus_txdata: out of bus->txq !!!
[204] dhd_bus_txdata: out of bus->txq !!!
[205] CMD: 53 <arg=21000020> FAIL raw_ints: 12034 masked ints: 4
[207] CMD: 52 <arg=12003800> FAIL raw_ints: 11030 masked ints: 1000
[207] CMD: 52 <arg=12003800> FAIL raw_ints: 11030 masked ints: 1000
[207] CMD: 52 <arg=12003800> FAIL raw_ints: 11030 masked ints: 1000
[207] CMD: 52 <arg=12003600> FAIL raw_ints: 11030 masked ints: 1000
[207] CMD: 52 <arg=12003600> FAIL raw_ints: 11030 masked ints: 1000
<20>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
iwconfig wlan0 mode managed
iwconfig wlan0 essid tplinklai
ifconfig wlan0 192.168.1.21
netperf -H 192.168.1.200 -t TCP_STREAM
<20><>SDIO<49><4F><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD>DATA BUSY<53>ļ<EFBFBD><C4BC><EFBFBD><E2A3AC>û<EFBFBD>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

View File

@@ -1,14 +0,0 @@
config BCM4319
bool "Broadcom 4319 wireless cards support"
depends on WLAN_80211 && MMC
select WIRELESS_EXT
select IEEE80211
select FW_LOADER
---help---
This module adds support for wireless adapters based on
Broadcom 4319 chipset.
This driver uses the kernel's wireless extensions subsystem.
If you choose to build a module, it'll be called dhd. Say M if
unsure.

View File

@@ -1,14 +0,0 @@
config BCM4319
bool "Broadcom 4319 wireless cards support"
depends on WLAN_80211 && MMC
select WIRELESS_EXT
select IEEE80211
select FW_LOADER
---help---
This module adds support for wireless adapters based on
Broadcom 4319 chipset.
This driver uses the kernel's wireless extensions subsystem.
If you choose to build a module, it'll be called dhd. Say M if
unsure.

View File

@@ -1,42 +1,24 @@
# bcm4319
DHDCFLAGS = -DLINUX -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD -DBCMWPA2 \
-DUNRELEASEDCHIP -Dlinux -DDHD_SDALIGN=64 -DMAX_HDR_READ=64 \
-DDHD_FIRSTREAD=64 -DDHD_GPL -DDHD_SCHED -DBDC -DTOE -DDHD_BCMEVENTS \
-DSHOW_EVENTS -DBCMSDIO -DDHD_GPL -DBCMLXSDMMC -DBCMPLATFORM_BUS \
-Wall -Wstrict-prototypes -Werror -DCUSTOMER_HW2 \
-DDHD_USE_STATIC_BUF -DDHD_DEBUG_TRAP -DSOFTAP -DSDIO_ISR_THREAD \
-DEMBEDDED_PLATFORM -DARP_OFFLOAD_SUPPORT -DPKT_FILTER_SUPPORT \
-DGET_CUSTOM_MAC_ENABLE -DSET_RANDOM_MAC_SOFTAP -DCSCAN \
-DKEEP_ALIVE -DCONFIG_US_NON_DFS_CHANNELS_ONLY \
-Idrivers/net/wireless/bcm4319 -Idrivers/net/wireless/bcm4319/include
RKWLCFGDIR = ../wifi_power
BROADCOM_SRC_DIR = drivers/net/wireless/bcm4319
#options defines dependent on platform board and applicantion requirements:
#-DOOB_INTR_ONLY -DMMC_SDIO_ABORT -DHW_OOB
EXTRA_CFLAGS += -I$(src) -I$(src)/include -I$(src)/$(RKWLCFGDIR)/
EXTRA_CFLAGS += -DLINUX -DSRCBASE=\"$(BROADCOM_SRC_DIR)\" -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD\
-DBCMWPA2 -DBCMWAPI_WPI
EXTRA_CFLAGS += -DUNRELEASEDCHIP -DOEM_ANDROID -DEMBEDDED_PLATFORM -DARP_OFFLOAD_SUPPORT -DPKT_FILTER_SUPPORT
EXTRA_CFLAGS += -DBCMSDIO -DDHD_GPL -DBCMLXSDMMC -DBCMPLATFORM_BUS
EXTRA_CFLAGS += -DSDIO_ISR_THREAD
EXTRA_CFLAGS += -DBDC -DTOE -DDHD_BCMEVENTS -DDHD_SCHED -DCSCAN
#EXTRA_CFLAGS += -DSHOW_EVENTS -DDHD_DEBUG -DSDTEST
#EXTRA_CFLAGS += -DBCMSDH_MODULE
#EXTRA_CFLAGS += -DCONFIG_WIFI_CONTROL_FUNC
DHDOFILES = dhd_linux.o linux_osl.o bcmutils.o dhd_common.o dhd_custom_gpio.o \
wl_iw.o siutils.o sbutils.o aiutils.o hndpmu.o bcmwifi.o dhd_sdio.o \
dhd_linux_sched.o dhd_cdc.o bcmsdh_sdmmc.o bcmsdh.o bcmsdh_linux.o \
bcmsdh_sdmmc_linux.o
bcmsdio-objs := bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o \
bcmsdh_sdmmc_linux.o
dhd-objs := dhd_common.o dhd_linux.o dhd_linux_sched.o dhd_sdio.o \
dhd_custom_gpio.o dhd_cdc.o
shared-objs := aiutils.o bcmutils.o bcmwifi.o hndpmu.o \
linux_osl.o sbutils.o siutils.o
wl-objs := wl_iw.o
bcm4319-objs := $(bcmsdio-objs) $(dhd-objs) $(shared-objs) $(wl-objs) $(RKWLCFGDIR)/wifi_power_ops.o
obj-$(CONFIG_BCM4319) += bcm4319.o $(RKWLCFGDIR)/wifi_power.o
default:
$(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
clean:
rm -rvf *.o *.ko *.mod.c *.o.cmd *.tmp_versions *.mod.o *.cmd modules.order Module.symvers .tmp_versions rkpub
find . -name '*.o' -exec rm -f {} \;
find . -name '.*.cmd' -exec rm -f {} \;
.PHONY: clean
obj-$(CONFIG_BCM4319) += bcm4319.o
bcm4319-objs += $(DHDOFILES)
EXTRA_CFLAGS = $(DHDCFLAGS)
EXTRA_LDFLAGS += --strip-debug

View File

@@ -1,13 +0,0 @@
EXTRA_CFLAGS += -I$(src)
rkcfg-y := \
wifi_power.o \
obj-$(CONFIG_BCM4319) += bcm4319.o rkcfg.o
$(obj)/bcm4319.o: $(obj)/bcm4319.uu
@echo "UUDE bcm4319.uu"
@uudecode $(obj)/bcm4319.uu -o $(obj)/bcm4319.o

View File

@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: bcmpcispi.c,v 1.22.2.4.4.5 2008/07/09 21:23:30 Exp $
* $Id: bcmpcispi.c,v 1.22.2.4.4.5.6.1 2010/08/13 00:26:05 Exp $
*/
#include <typedefs.h>
@@ -606,18 +606,23 @@ spi_spinbits(sdioh_info_t *sd)
spin_count = 0;
while ((SPIPCI_RREG(sd->osh, &regs->spih_stat) & SPIH_WFEMPTY) == 0) {
if (spin_count > SPI_SPIN_BOUND) {
ASSERT(FALSE); /* Spin bound exceeded */
sd_err(("%s: SPIH_WFEMPTY spin bits out of bound %u times \n",
__FUNCTION__, spin_count));
ASSERT(FALSE);
}
spin_count++;
}
spin_count = 0;
/* Wait for SPI Transfer state machine to return to IDLE state.
* The state bits are only implemented in Rev >= 5 FPGA. These
* bits are hardwired to 00 for Rev < 5, so this check doesn't cause
* any problems.
*/
spin_count = 0;
while ((SPIPCI_RREG(osh, &regs->spih_stat) & SPIH_STATE_MASK) != 0) {
if (spin_count > SPI_SPIN_BOUND) {
sd_err(("%s: SPIH_STATE_MASK spin bits out of bound %u times \n",
__FUNCTION__, spin_count));
ASSERT(FALSE);
}
spin_count++;

View File

@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: bcmsdh_linux.c,v 1.42.10.10.2.12 2010/03/10 03:09:48 Exp $
* $Id: bcmsdh_linux.c,v 1.42.10.10.2.14.4.2 2010/09/15 00:30:11 Exp $
*/
/**
@@ -76,6 +76,10 @@ struct bcmsdh_hc {
void *ch;
unsigned int oob_irq;
unsigned long oob_flags; /* OOB Host specifiction as edge and etc */
bool oob_irq_registered;
#if defined(OOB_INTR_ONLY)
spinlock_t irq_lock;
#endif
};
static bcmsdh_hc_t *sdhcinfo = NULL;
@@ -187,7 +191,12 @@ int bcmsdh_probe(struct device *dev)
#endif /* BCMLXSDMMC */
#if defined(OOB_INTR_ONLY)
irq_flags = IRQF_TRIGGER_FALLING;
#ifdef HW_OOB
irq_flags = \
IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE;
#else
irq_flags = IRQF_TRIGGER_FALLING;
#endif /* HW_OOB */
irq = dhd_customer_oob_irq_map(&irq_flags);
if (irq < 0) {
SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__));
@@ -226,6 +235,10 @@ int bcmsdh_probe(struct device *dev)
sdhc->sdh = sdh;
sdhc->oob_irq = irq;
sdhc->oob_flags = irq_flags;
sdhc->oob_irq_registered = FALSE; /* to make sure.. */
#if defined(OOB_INTR_ONLY)
spin_lock_init(&sdhc->irq_lock);
#endif
/* chain SDIO Host Controller info together */
sdhc->next = sdhcinfo;
@@ -332,18 +345,18 @@ static struct pci_driver bcmsdh_pci_driver = {
#endif
suspend: NULL,
resume: NULL,
};
};
extern uint sd_pci_slot; /* Force detection to a particular PCI */
/* slot only . Allows for having multiple */
/* WL devices at once in a PC */
/* Only one instance of dhd will be */
/* useable at a time */
/* Upper word is bus number, */
/* lower word is slot number */
/* Default value of 0xFFFFffff turns this */
/* off */
/* slot only . Allows for having multiple */
/* WL devices at once in a PC */
/* Only one instance of dhd will be */
/* usable at a time */
/* Upper word is bus number, */
/* lower word is slot number */
/* Default value of 0xFFFFffff turns this */
/* off */
module_param(sd_pci_slot, uint, 0);
@@ -366,20 +379,21 @@ bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pdev->bus->number != (sd_pci_slot>>16) ||
PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) {
SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n",
__FUNCTION__,
bcmsdh_chipmatch(pdev->vendor, pdev->device)
?"Found compatible SDIOHC"
:"Probing unknown device",
pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor,
pdev->device));
__FUNCTION__,
bcmsdh_chipmatch(pdev->vendor, pdev->device) ?
"Found compatible SDIOHC" :
"Probing unknown device",
pdev->bus->number, PCI_SLOT(pdev->devfn),
pdev->vendor, pdev->device));
return -ENODEV;
}
SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n",
__FUNCTION__,
bcmsdh_chipmatch(pdev->vendor, pdev->device)
?"Using compatible SDIOHC"
:"WARNING, forced use of unkown device",
pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device));
__FUNCTION__,
bcmsdh_chipmatch(pdev->vendor, pdev->device) ?
"Using compatible SDIOHC" :
"WARNING, forced use of unkown device",
pdev->bus->number, PCI_SLOT(pdev->devfn),
pdev->vendor, pdev->device));
}
if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) ||
@@ -440,7 +454,7 @@ bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
rc = pci_enable_device(pdev);
if (rc) {
SDLX_MSG(("%s: Cannot enble PCI device\n", __FUNCTION__));
SDLX_MSG(("%s: Cannot enable PCI device\n", __FUNCTION__));
goto err;
}
if (!(sdh = bcmsdh_attach(osh, (void *)(uintptr)pci_resource_start(pdev, 0),
@@ -521,8 +535,28 @@ bcmsdh_register(bcmsdh_driver_t *driver)
drvinfo = *driver;
#if defined(BCMPLATFORM_BUS)
#if defined(BCMLXSDMMC)
SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
error = sdio_function_init();
#else
SDLX_MSG(("Intel PXA270 SDIO Driver\n"));
error = driver_register(&bcmsdh_driver);
#endif /* defined(BCMLXSDMMC) */
return error;
#endif /* defined(BCMPLATFORM_BUS) */
#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
if (!(error = pci_module_init(&bcmsdh_pci_driver)))
return 0;
#else
if (!(error = pci_register_driver(&bcmsdh_pci_driver)))
return 0;
#endif
SDLX_MSG(("%s: pci_module_init failed 0x%x\n", __FUNCTION__, error));
#endif /* BCMPLATFORM_BUS */
return error;
}
@@ -548,20 +582,35 @@ bcmsdh_unregister(void)
}
#if defined(OOB_INTR_ONLY)
void bcmsdh_oob_intr_set(bool enable)
{
static bool curstate = 1;
unsigned long flags;
spin_lock_irqsave(&sdhcinfo->irq_lock, flags);
if (curstate != enable) {
if (enable)
enable_irq(sdhcinfo->oob_irq);
else
disable_irq_nosync(sdhcinfo->oob_irq);
curstate = enable;
}
spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags);
}
static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
{
dhd_pub_t *dhdp;
dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev);
bcmsdh_oob_intr_set(0);
if (dhdp == NULL) {
disable_irq(sdhcinfo->oob_irq);
SDLX_MSG(("Out of band GPIO interrupt fired way too early\n"));
return IRQ_HANDLED;
}
WAKE_LOCK_TIMEOUT(dhdp, WAKE_LOCK_TMOUT, 25);
dhdsdio_isr((void *)dhdp->bus);
return IRQ_HANDLED;
@@ -573,21 +622,41 @@ int bcmsdh_register_oob_intr(void * dhdp)
SDLX_MSG(("%s Enter\n", __FUNCTION__));
/* Example of HW_OOB for HW2: please refer to your host specifiction */
/* sdhcinfo->oob_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */
dev_set_drvdata(sdhcinfo->dev, dhdp);
if (!sdhcinfo->oob_irq_registered) {
SDLX_MSG(("%s IRQ=%d Type=%X \n", __FUNCTION__, \
(int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags));
/* Refer to customer Host IRQ docs about proper irqflags definition */
error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags,
"bcmsdh_sdmmc", NULL);
if (error)
return -ENODEV;
/* Refer to customer Host IRQ docs about proper irqflags definition */
error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags,
"bcmsdh_sdmmc", NULL);
if (error)
return -ENODEV;
set_irq_wake(sdhcinfo->oob_irq, 1);
set_irq_wake(sdhcinfo->oob_irq, 1);
sdhcinfo->oob_irq_registered = TRUE;
}
return 0;
}
void bcmsdh_set_irq(int flag)
{
if (sdhcinfo->oob_irq_registered) {
SDLX_MSG(("%s Flag = %d", __FUNCTION__, flag));
if (flag) {
enable_irq(sdhcinfo->oob_irq);
enable_irq_wake(sdhcinfo->oob_irq);
} else {
disable_irq_wake(sdhcinfo->oob_irq);
disable_irq(sdhcinfo->oob_irq);
}
}
}
void bcmsdh_unregister_oob_intr(void)
{
SDLX_MSG(("%s: Enter\n", __FUNCTION__));
@@ -595,14 +664,7 @@ void bcmsdh_unregister_oob_intr(void)
set_irq_wake(sdhcinfo->oob_irq, 0);
disable_irq(sdhcinfo->oob_irq); /* just in case.. */
free_irq(sdhcinfo->oob_irq, NULL);
}
void bcmsdh_oob_intr_set(bool enable)
{
if (enable)
enable_irq(sdhcinfo->oob_irq);
else
disable_irq(sdhcinfo->oob_irq);
sdhcinfo->oob_irq_registered = FALSE;
}
#endif /* defined(OOB_INTR_ONLY) */
/* Module parameters specific to each host-controller driver */

View File

@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: bcmsdh_sdmmc.c,v 1.1.2.5.6.29 2010/03/19 17:16:08 Exp $
* $Id: bcmsdh_sdmmc.c,v 1.1.2.5.6.30.4.1 2010/09/02 23:12:21 Exp $
*/
#include <typedefs.h>
@@ -55,7 +55,7 @@ extern void sdio_function_cleanup(void);
#if !defined(OOB_INTR_ONLY)
static void IRQHandler(struct sdio_func *func);
static void IRQHandlerF2(struct sdio_func *func);
#endif
#endif /* !defined(OOB_INTR_ONLY) */
static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr);
extern int sdio_reset_comm(struct mmc_card *card);
@@ -675,6 +675,7 @@ sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable)
data = 3; /* enable hw oob interrupt */
else
data = 4; /* disable hw oob interrupt */
data |= 4; /* Active HIGH */
status = sdioh_request_byte(sd, SDIOH_WRITE, 0, 0xf2, &data);
return status;
@@ -1064,14 +1065,18 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u
return (Status);
}
/* this function performs "abort" for both of host & device */
extern int
sdioh_abort(sdioh_info_t *sd, uint func)
{
#if defined(MMC_SDIO_ABORT)
char t_func = (char) func;
#endif /* defined(MMC_SDIO_ABORT) */
sd_trace(("%s: Enter\n", __FUNCTION__));
#if defined(MMC_SDIO_ABORT)
/* issue abort cmd52 command through F1 */
sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT, (uint8 *)&func);
sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT, &t_func);
#endif /* defined(MMC_SDIO_ABORT) */
sd_trace(("%s: Exit\n", __FUNCTION__));
@@ -1215,9 +1220,9 @@ sdioh_start(sdioh_info_t *si, int stage)
2.6.27. The implementation prior to that is buggy, and needs broadcom's
patch for it
*/
// if ((ret = sdio_reset_comm(gInstance->func[0]->card)))
// sd_err(("%s Failed, error = %d\n", __FUNCTION__, ret));
// else {
if ((ret = sdio_reset_comm(gInstance->func[0]->card)))
sd_err(("%s Failed, error = %d\n", __FUNCTION__, ret));
else {
sd->num_funcs = 2;
sd->sd_blockmode = TRUE;
sd->use_client_ints = TRUE;
@@ -1250,7 +1255,7 @@ sdioh_start(sdioh_info_t *si, int stage)
}
sdioh_sdmmc_card_enablefuncs(sd);
// }
}
} else {
#if !defined(OOB_INTR_ONLY)
sdio_claim_host(gInstance->func[0]);

View File

@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: bcmsdh_sdmmc_linux.c,v 1.1.2.5.6.15 2010/04/14 21:11:46 Exp $
* $Id: bcmsdh_sdmmc_linux.c,v 1.1.2.5.6.17 2010/08/13 00:36:19 Exp $
*/
#include <typedefs.h>
@@ -34,15 +34,20 @@
#include <linux/mmc/core.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#if !defined(SDIO_VENDOR_ID_BROADCOM)
#define SDIO_VENDOR_ID_BROADCOM 0x02d0
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */
#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */
#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000
#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)
#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */
#if !defined(SDIO_DEVICE_ID_BROADCOM_4325)
#define SDIO_DEVICE_ID_BROADCOM_4325 0x0000
#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */
#if !defined(SDIO_DEVICE_ID_BROADCOM_4329)
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
@@ -51,15 +56,10 @@
#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
#include <bcmsdh_sdmmc.h>
#include <dhd_dbg.h>
struct sdio_func *wifi_sdio_func = NULL;
EXPORT_SYMBOL(wifi_sdio_func);
extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
@@ -113,13 +113,9 @@ static int bcmsdh_sdmmc_probe(struct sdio_func *func,
ret = bcmsdh_probe(&sdmmc_dev);
}
wifi_sdio_func = func;
//printk("get wifi_sdio_func\n");
return ret;
}
extern int wifi_func_removed;
static void bcmsdh_sdmmc_remove(struct sdio_func *func)
{
sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__));
@@ -129,16 +125,15 @@ static void bcmsdh_sdmmc_remove(struct sdio_func *func)
sd_info(("Function#: 0x%04x\n", func->num));
if (func->num == 2) {
sd_trace(("F2 found, calling bcmsdh_probe...\n"));
sd_trace(("F2 found, calling bcmsdh_remove...\n"));
bcmsdh_remove(&sdmmc_dev);
}
wifi_func_removed = 1;
wifi_sdio_func = NULL;
}
/* devices we support, null terminated */
static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) },
@@ -235,8 +230,8 @@ bcmsdh_module_cleanup(void)
sdio_function_cleanup();
}
//module_init(bcmsdh_module_init);
//module_exit(bcmsdh_module_cleanup);
module_init(bcmsdh_module_init);
module_exit(bcmsdh_module_cleanup);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION(DESCRIPTION);
@@ -258,6 +253,7 @@ int sdio_function_init(void)
bzero(&sdmmc_dev, sizeof(sdmmc_dev));
error = sdio_register_driver(&bcmsdh_sdmmc_driver);
return error;
}

View File

@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: bcmsdstd.c,v 1.64.4.1.4.4.2.17 2010/03/10 03:09:48 Exp $
* $Id: bcmsdstd.c,v 1.64.4.1.4.4.2.18 2010/08/17 17:00:48 Exp $
*/
#include <typedefs.h>
@@ -119,7 +119,7 @@ extern void sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data);
void
sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data)
{
*(volatile uint16 *)(sd->mem_space + reg) = (volatile uint16) data;
*(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
sd_ctrl(("16: W Reg 0x%02x, Data 0x%x\n", reg, data));
}
@@ -129,7 +129,7 @@ sdstd_or_reg16(sdioh_info_t *sd, uint reg, uint16 val)
volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
sd_ctrl(("16: OR Reg 0x%02x, Val 0x%x\n", reg, val));
data |= val;
*(volatile uint16 *)(sd->mem_space + reg) = (volatile uint16)data;
*(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
}
static void
@@ -140,7 +140,7 @@ sdstd_mod_reg16(sdioh_info_t *sd, uint reg, int16 mask, uint16 val)
sd_ctrl(("16: MOD Reg 0x%02x, Mask 0x%x, Val 0x%x\n", reg, mask, val));
data &= ~mask;
data |= (val & mask);
*(volatile uint16 *)(sd->mem_space + reg) = (volatile uint16)data;
*(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
}
@@ -155,7 +155,7 @@ sdstd_rreg(sdioh_info_t *sd, uint reg)
static inline void
sdstd_wreg(sdioh_info_t *sd, uint reg, uint32 data)
{
*(volatile uint32 *)(sd->mem_space + reg) = (volatile uint32)data;
*(volatile uint32 *)(sd->mem_space + reg) = (uint32)data;
sd_ctrl(("32: W Reg 0x%02x, Data 0x%x\n", reg, data));
}
@@ -164,7 +164,7 @@ sdstd_wreg(sdioh_info_t *sd, uint reg, uint32 data)
static inline void
sdstd_wreg8(sdioh_info_t *sd, uint reg, uint8 data)
{
*(volatile uint8 *)(sd->mem_space + reg) = (volatile uint8)data;
*(volatile uint8 *)(sd->mem_space + reg) = (uint8)data;
sd_ctrl(("08: W Reg 0x%02x, Data 0x%x\n", reg, data));
}
static uint8
@@ -287,7 +287,7 @@ sdioh_detach(osl_t *osh, sdioh_info_t *sd)
return SDIOH_API_RC_SUCCESS;
}
/* Configure callback to client when we recieve client interrupt */
/* Configure callback to client when we receive client interrupt */
extern SDIOH_API_RC
sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
{
@@ -2778,10 +2778,6 @@ sdstd_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, uint32 addr, int n
data++;
}
/* Handle < 4 bytes. wlc_pio.c currently (as of 12/20/05) truncates buflen
* to be evenly divisable by 4. However dongle passes arbitrary lengths,
* so handle it here
*/
bytes = blocksize % 4;
/* If no leftover bytes, go to next block */
@@ -2898,7 +2894,8 @@ set_client_block_size(sdioh_info_t *sd, int func, int block_size)
}
/* Reset and re-initialize the device */
int sdioh_sdio_reset(sdioh_info_t *si)
int
sdioh_sdio_reset(sdioh_info_t *si)
{
uint8 hreg;

View File

@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: bcmsdstd_linux.c,v 1.11.18.2 2008/05/28 18:36:56 Exp $
* $Id: bcmsdstd_linux.c,v 1.11.18.2.16.1 2010/08/17 17:03:13 Exp $
*/
#include <typedefs.h>
@@ -186,7 +186,9 @@ sdstd_lock(sdioh_info_t *sd)
spin_lock_irqsave(&sdos->lock, flags);
if (sd->lockcount) {
sd_err(("%s: Already locked!\n", __FUNCTION__));
sd_err(("%s: Already locked! called from %p\n",
__FUNCTION__,
__builtin_return_address(0)));
ASSERT(sd->lockcount == 0);
}
sdstd_devintr_off(sd);

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: dhd.h,v 1.32.4.7.2.4.14.44 2010/06/03 21:27:48 Exp $
* $Id: dhd.h,v 1.32.4.7.2.4.14.49.4.7 2010/11/12 22:48:36 Exp $
*/
/****************
@@ -35,9 +35,6 @@
#define _dhd_h_
#if defined(LINUX)
#if defined(CHROMIUMOS_COMPAT_WIRELESS)
#include <linux/sched.h>
#endif
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -47,11 +44,10 @@
#include <linux/random.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
#include <linux/wakelock.h>
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
/* The kernel threading is sdio-specific */
#else /* LINUX */
#define ENOMEM 1
@@ -64,6 +60,11 @@
#include <wlioctl.h>
#ifdef DHD_DEBUG
#ifndef DHD_DEBUG_TRAP
#define DHD_DEBUG_TRAP
#endif
#endif
/* Forward decls */
struct dhd_bus;
@@ -86,9 +87,11 @@ enum dhd_bus_wake_state {
WAKE_LOCK_TMOUT,
WAKE_LOCK_WATCHDOG,
WAKE_LOCK_LINK_DOWN_TMOUT,
WAKE_LOCK_PNO_FIND_TMOUT,
WAKE_LOCK_SOFTAP_SET,
WAKE_LOCK_SOFTAP_STOP,
WAKE_LOCK_SOFTAP_START,
WAKE_LOCK_SOFTAP_THREAD,
WAKE_LOCK_MAX
};
enum dhd_prealloc_index {
@@ -141,7 +144,7 @@ typedef struct dhd_pub {
ulong rx_readahead_cnt; /* Number of packets where header read-ahead was used. */
ulong tx_realloc; /* Number of tx packets we had to realloc for headroom */
ulong fc_packets; /* Number of flow control pkts recvd */
ulong fc_packets; /* Number of flow control pkts recvd */
/* Last error return */
int bcmerror;
@@ -150,6 +153,14 @@ typedef struct dhd_pub {
/* Last error from dongle */
int dongle_error;
/* Suspend disable flag and "in suspend" flag */
int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */
int in_suspend; /* flag set to 1 when early suspend called */
#ifdef PNO_SUPPORT
int pno_enable; /* pno status : "1" is pno enable */
#endif /* PNO_SUPPORT */
int dtim_skip; /* dtim skip , default 0 means wake each dtim */
/* Pkt filter defination */
char * pktfilter[100];
int pktfilter_count;
@@ -157,26 +168,19 @@ typedef struct dhd_pub {
uint8 country_code[WLC_CNTRY_BUF_SZ];
char eventmask[WL_EVENTING_MASK_LEN];
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
struct wake_lock wakelock[WAKE_LOCK_MAX];
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
struct mutex wl_start_stop_lock; /* lock/unlock for Android start/stop */
struct mutex wl_softap_lock; /* lock/unlock for any SoftAP/STA settings */
#endif
} dhd_pub_t;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
#define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
#define _DHD_PM_RESUME_WAIT(a, b) do {\
#define _DHD_PM_RESUME_WAIT(a, b) do { \
int retry = 0; \
smp_mb(); \
while (dhd_mmc_suspend && retry++ != b) { \
wait_event_timeout(a, FALSE, HZ/100); \
wait_event_interruptible_timeout(a, FALSE, HZ/100); \
} \
} while (0)
#define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 30)
#define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 30)
#define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0)
#define DHD_PM_RESUME_RETURN_ERROR(a) do { if (dhd_mmc_suspend) return a; } while (0)
#define DHD_PM_RESUME_RETURN do { if (dhd_mmc_suspend) return; } while (0)
@@ -185,12 +189,12 @@ typedef struct dhd_pub {
#define SPINWAIT_SLEEP(a, exp, us) do { \
uint countdown = (us) + 9999; \
while ((exp) && (countdown >= 10000)) { \
wait_event_timeout(a, FALSE, HZ/100); \
wait_event_interruptible_timeout(a, FALSE, HZ/100); \
countdown -= 10000; \
} \
} while (0)
#else
#else
#define DHD_PM_RESUME_WAIT_INIT(a)
#define DHD_PM_RESUME_WAIT(a)
@@ -207,111 +211,20 @@ typedef struct dhd_pub {
} \
} while (0)
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
#define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */
inline static void MUTEX_LOCK_INIT(dhd_pub_t * dhdp)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
mutex_init(&dhdp->wl_start_stop_lock);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
}
inline static void MUTEX_LOCK(dhd_pub_t * dhdp)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
mutex_lock(&dhdp->wl_start_stop_lock);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
}
inline static void MUTEX_UNLOCK(dhd_pub_t * dhdp)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
mutex_unlock(&dhdp->wl_start_stop_lock);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
}
inline static void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t * dhdp)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
mutex_init(&dhdp->wl_softap_lock);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
}
inline static void MUTEX_LOCK_SOFTAP_SET(dhd_pub_t * dhdp)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
mutex_lock(&dhdp->wl_softap_lock);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
}
inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
mutex_unlock(&dhdp->wl_softap_lock);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
extern struct mutex g_wl_ss_scan_lock; /* lock/unlock for Scan/Cache settings */
#endif
inline static void MUTEX_LOCK_WL_SCAN_SET_INIT(void)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
mutex_init(&g_wl_ss_scan_lock);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
}
inline static void MUTEX_LOCK_WL_SCAN_SET(void)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
mutex_lock(&g_wl_ss_scan_lock);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
}
inline static void MUTEX_UNLOCK_WL_SCAN_SET(void)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
mutex_unlock(&g_wl_ss_scan_lock);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
}
inline static void WAKE_LOCK_INIT(dhd_pub_t * dhdp, int index, char * y)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
wake_lock_init(&dhdp->wakelock[index], WAKE_LOCK_SUSPEND, y);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
}
inline static void WAKE_LOCK(dhd_pub_t * dhdp, int index)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
wake_lock(&dhdp->wakelock[index]);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
}
inline static void WAKE_UNLOCK(dhd_pub_t * dhdp, int index)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
wake_unlock(&dhdp->wakelock[index]);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
}
inline static void WAKE_LOCK_TIMEOUT(dhd_pub_t * dhdp, int index, long time)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
wake_lock_timeout(&dhdp->wakelock[index], time);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
}
inline static void WAKE_LOCK_DESTROY(dhd_pub_t * dhdp, int index)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
wake_lock_destroy(&dhdp->wakelock[index]);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
}
/* Wakelock Functions */
extern int dhd_os_wake_lock(dhd_pub_t *pub);
extern int dhd_os_wake_unlock(dhd_pub_t *pub);
extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub);
extern int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub);
extern void dhd_os_start_lock(dhd_pub_t *pub);
extern void dhd_os_start_unlock(dhd_pub_t *pub);
extern unsigned long dhd_os_spin_lock(dhd_pub_t *pub);
extern void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags);
typedef struct dhd_if_event {
uint8 ifidx;
@@ -378,7 +291,7 @@ extern void dhd_os_sdlock_rxq(dhd_pub_t * pub);
extern void dhd_os_sdunlock_rxq(dhd_pub_t * pub);
extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t * pub);
extern void dhd_customer_gpio_wlan_ctrl(int onoff);
extern int dhd_custom_get_mac_address(unsigned char *buf);
extern int dhd_custom_get_mac_address(unsigned char *buf);
extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub);
extern void dhd_os_sdlock_eventq(dhd_pub_t * pub);
extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub);
@@ -440,8 +353,11 @@ typedef enum cust_gpio_modes {
WLAN_POWER_ON,
WLAN_POWER_OFF
} cust_gpio_modes_t;
extern int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag);
extern int wl_iw_send_priv_event(struct net_device *dev, char *flag);
extern int net_os_send_hang_message(struct net_device *dev);
/*
* Insmod parameters for debug/test
*/
@@ -491,6 +407,10 @@ extern uint dhd_sdiod_drive_strength;
/* Override to force tx queueing all the time */
extern uint dhd_force_tx_queueing;
/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */
#define KEEP_ALIVE_PERIOD 55000
#define NULL_PKT_STR "null_pkt"
#ifdef SDTEST
/* Echo packet generator (SDIO), pkts/s */
extern uint dhd_pktgen;
@@ -511,21 +431,8 @@ extern char nv_path[MOD_PARAM_PATHLEN];
#define DHD_DEL_IF -0xe
#define DHD_BAD_IF -0xf
#ifdef APSTA_PINGTEST
#define MAX_GUEST 8
#endif
extern void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar);
extern void dhd_wait_event_wakeup(dhd_pub_t*dhd);
//hojie: for wifi power control
#define ANDROID_POWER_SAVE 1
#ifndef CONFIG_BCM4319_FW_PATH
#define CONFIG_BCM4319_FW_PATH "/etc/firmware/sdio-g-cdc-full11n-reclaim-roml-wme.bin"
#endif
#ifndef CONFIG_BCM4319_NVRAM_PATH
#define CONFIG_BCM4319_NVRAM_PATH "/etc/firmware/nvram_4319_201008.txt"
#endif
#endif /* _dhd_h_ */

View File

@@ -24,7 +24,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: dhd_bus.h,v 1.4.6.3.2.3.6.6 2010/05/17 18:18:13 Exp $
* $Id: dhd_bus.h,v 1.4.6.3.2.3.6.7 2010/08/13 01:35:24 Exp $
*/
#ifndef _dhd_bus_h_
@@ -63,7 +63,7 @@ extern bool dhd_bus_watchdog(dhd_pub_t *dhd);
#ifdef DHD_DEBUG
/* Device console input function */
extern int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen);
#endif
#endif /* DHD_DEBUG */
/* Deferred processing for the bus, return TRUE requests reschedule */
extern bool dhd_bus_dpc(struct dhd_bus *bus);

View File

@@ -40,13 +40,11 @@
#include <dhd_proto.h>
#include <dhd_bus.h>
#include <dhd_dbg.h>
#ifdef CUSTOMER_HW2
int wifi_get_mac_addr(unsigned char *buf);
#endif
uint8 wlan_mac_addr[ETHER_ADDR_LEN];
extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
/* Packet alignment for most efficient SDIO (can change based on platform) */
#ifndef DHD_SDALIGN
#define DHD_SDALIGN 32
@@ -78,11 +76,13 @@ dhdcdc_msg(dhd_pub_t *dhd)
{
dhd_prot_t *prot = dhd->prot;
int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t);
int ret;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
/*
* NOTE : cdc->msg.len holds the desired length of the buffer to be
dhd_os_wake_lock(dhd);
/* NOTE : cdc->msg.len holds the desired length of the buffer to be
* returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
* is actually sent to the dongle
*/
@@ -90,7 +90,9 @@ dhdcdc_msg(dhd_pub_t *dhd)
len = CDC_MAX_MSG_SIZE;
/* Send request */
return dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len);
ret = dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len);
dhd_os_wake_unlock(dhd);
return ret;
}
static int
@@ -201,7 +203,7 @@ dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
cdc_ioctl_t *msg = &prot->msg;
int ret = 0;
uint32 flags, id;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len));
@@ -250,7 +252,7 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len)
{
dhd_prot_t *prot = dhd->prot;
int ret = -1;
if (dhd->busstate == DHD_BUS_DOWN) {
DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
return ret;
@@ -323,23 +325,12 @@ dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid);
}
#ifdef APSTA_PINGTEST
extern struct ether_addr guest_eas[MAX_GUEST];
#endif
void
dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf)
{
#ifdef BDC
struct bdc_header *h;
#ifdef APSTA_PINGTEST
struct ether_header *eh;
int i;
#ifdef DHD_DEBUG
char eabuf1[ETHER_ADDR_STR_LEN];
char eabuf2[ETHER_ADDR_STR_LEN];
#endif /* DHD_DEBUG */
#endif /* APSTA_PINGTEST */
#endif /* BDC */
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@@ -347,9 +338,6 @@ dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf)
#ifdef BDC
/* Push BDC header used to convey priority for buses that don't */
#ifdef APSTA_PINGTEST
eh = (struct ether_header *)PKTDATA(dhd->osh, pktbuf);
#endif
PKTPUSH(dhd->osh, pktbuf, BDC_HEADER_LEN);
@@ -362,19 +350,6 @@ dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf)
h->priority = (PKTPRIO(pktbuf) & BDC_PRIORITY_MASK);
h->flags2 = 0;
#ifdef APSTA_PINGTEST
for (i = 0; i < MAX_GUEST; ++i) {
if (!ETHER_ISNULLADDR(eh->ether_dhost) &&
bcmp(eh->ether_dhost, guest_eas[i].octet, ETHER_ADDR_LEN) == 0) {
DHD_TRACE(("send on if 1; sa %s, da %s\n",
bcm_ether_ntoa((struct ether_addr *)(eh->ether_shost), eabuf1),
bcm_ether_ntoa((struct ether_addr *)(eh->ether_dhost), eabuf2)));
/* assume all guest STAs are on interface 1 */
h->flags2 = 1;
break;
}
}
#endif /* APSTA_PINGTEST */
h->rssi = 0;
#endif /* BDC */
BDC_SET_IF_IDX(h, ifidx);
@@ -529,6 +504,7 @@ dhd_prot_init(dhd_pub_t *dhd)
return ret;
}
memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN);
memcpy(wlan_mac_addr, buf, ETHER_ADDR_LEN);
dhd_os_proto_unblock(dhd);

View File

@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: dhd_common.c,v 1.5.6.8.2.6.6.65 2010/07/07 00:05:07 Exp $
* $Id: dhd_common.c,v 1.5.6.8.2.6.6.69.4.20 2010/12/20 23:37:28 Exp $
*/
#include <typedefs.h>
#include <osl.h>
@@ -37,15 +37,23 @@
#include <dhd_dbg.h>
#include <msgtrace.h>
#include <wlioctl.h>
#define CONFIG_BCM4319_FW_PATH "/system/etc/firmware/fw_bcm4319.bin"
#define CONFIG_BCM4319_NVRAM_PATH "/system/etc/firmware/nvram.txt"
#ifdef SET_RANDOM_MAC_SOFTAP
#include <linux/random.h>
#include <linux/jiffies.h>
#endif
#ifdef GET_CUSTOM_MAC_ENABLE
int wifi_get_mac_addr(unsigned char *buf);
#endif /* GET_CUSTOM_MAC_ENABLE */
int dhd_msg_level;
#if defined(CSCAN)
#include <wl_iw.h>
#endif
char fw_path[MOD_PARAM_PATHLEN];
char nv_path[MOD_PARAM_PATHLEN];
@@ -66,6 +74,13 @@ extern int dhd_wl_ioctl(dhd_pub_t *dhd, uint cmd, char *buf, uint buflen);
void dhd_iscan_lock(void);
void dhd_iscan_unlock(void);
#if defined(SOFTAP)
extern bool ap_fw_loaded;
#endif
#if defined(KEEP_ALIVE)
int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on);
#endif /* KEEP_ALIVE */
/* Packet alignment for most efficient SDIO (can change based on platform) */
#ifndef DHD_SDALIGN
#define DHD_SDALIGN 32
@@ -229,7 +244,6 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
dhd_msg_level = int_val;
break;
case IOV_GVAL(IOV_BCMERRORSTR):
strncpy((char *)arg, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN);
((char *)arg)[BCME_STRLEN - 1] = 0x00;
@@ -508,9 +522,6 @@ dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen)
return bcmerror;
}
#ifdef APSTA_PINGTEST
struct ether_addr guest_eas[MAX_GUEST];
#endif
#ifdef SHOW_EVENTS
static void
@@ -619,16 +630,6 @@ wl_show_host_event(wl_event_msg_t *event, void *event_data)
case WLC_E_ASSOC_IND:
case WLC_E_REASSOC_IND:
#ifdef APSTA_PINGTEST
{
int i;
for (i = 0; i < MAX_GUEST; ++i)
if (ETHER_ISNULLADDR(&guest_eas[i]))
break;
if (i < MAX_GUEST)
bcopy(event->addr.octet, guest_eas[i].octet, ETHER_ADDR_LEN);
}
#endif /* APSTA_PINGTEST */
DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
break;
@@ -649,18 +650,6 @@ wl_show_host_event(wl_event_msg_t *event, void *event_data)
case WLC_E_DEAUTH_IND:
case WLC_E_DISASSOC_IND:
#ifdef APSTA_PINGTEST
{
int i;
for (i = 0; i < MAX_GUEST; ++i) {
if (bcmp(guest_eas[i].octet, event->addr.octet,
ETHER_ADDR_LEN) == 0) {
bzero(guest_eas[i].octet, ETHER_ADDR_LEN);
break;
}
}
}
#endif /* APSTA_PINGTEST */
DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, eabuf, (int)reason));
break;
@@ -966,6 +955,7 @@ void print_buf(void *pbuf, int len, int bytes_per_line)
#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
#ifdef PKT_FILTER_SUPPORT
/* Convert user's input in hex pattern to byte-size mask */
static int
wl_pattern_atoh(char *src, char *dst)
@@ -1195,7 +1185,9 @@ fail:
if (buf)
MFREE(dhd->osh, buf, BUF_SIZE);
}
#endif
#ifdef ARP_OFFLOAD_SUPPORT
void
dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode)
{
@@ -1229,6 +1221,7 @@ dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable)
DHD_TRACE(("%s: successfully enabed ARP offload to %d\n",
__FUNCTION__, arp_enable));
}
#endif
int
dhd_preinit_ioctls(dhd_pub_t *dhd)
@@ -1239,20 +1232,26 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
uint power_mode = PM_FAST;
uint32 dongle_align = DHD_SDALIGN;
uint32 glom = 0;
uint bcn_timeout = 3;
uint bcn_timeout = 4;
int scan_assoc_time = 40;
int scan_unassoc_time = 80;
#ifdef GET_CUSTOM_MAC_ENABLE
int scan_unassoc_time = 40;
uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */
#if defined(SOFTAP)
uint dtim = 1;
#endif
int ret = 0;
#ifdef GET_CUSTOM_MAC_ENABLE
struct ether_addr ea_addr;
#endif /* GET_CUSTOM_MAC_ENABLE */
dhd_os_proto_block(dhd);
#ifdef GET_CUSTOM_MAC_ENABLE
/* Read MAC address from external customer place
** NOTE that default mac address has to be present in otp or nvram file to bring up
** firmware but unique per board mac address maybe provided by customer code
/*
** Read MAC address from external customer place
** NOTE that default mac address has to be present in otp or nvram file
** to bring up firmware but unique per board mac address maybe provided
** by customer code
*/
ret = dhd_custom_get_mac_address(ea_addr.octet);
if (!ret) {
@@ -1260,23 +1259,42 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf));
if (ret < 0) {
DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret));
}
else
} else
memcpy(dhd->mac.octet, (void *)&ea_addr, ETHER_ADDR_LEN);
}
#endif /* GET_CUSTOM_MAC_ENABLE */
#endif /* GET_CUSTOM_MAC_ENABLE */
/*
* Initially, country code maybe US, in this situation,
* Just 11 channels are supported, but 13 channels should be supported
* in China, so we change contry code to EU (Eurapor). -- Yongle Lai
*/
strcpy(dhd->country_code, "EU");
dhd->country_code[2] = '\0';
/*
* Set Country code.
*/
#ifdef SET_RANDOM_MAC_SOFTAP
if (strstr(fw_path, "apsta") != NULL) {
uint rand_mac;
srandom32((uint)jiffies);
rand_mac = random32();
iovbuf[0] = 0x02; /* locally administered bit */
iovbuf[1] = 0x1A;
iovbuf[2] = 0x11;
iovbuf[3] = (unsigned char)(rand_mac & 0x0F) | 0xF0;
iovbuf[4] = (unsigned char)(rand_mac >> 8);
iovbuf[5] = (unsigned char)(rand_mac >> 16);
printk("Broadcom Dongle Host Driver mac=%02x:%02x:%02x:%02x:%02x:%02x\n",
iovbuf[0], iovbuf[1], iovbuf[2], iovbuf[3], iovbuf[4], iovbuf[5]);
bcm_mkiovar("cur_etheraddr", (void *)iovbuf, ETHER_ADDR_LEN, buf, sizeof(buf));
ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf));
if (ret < 0) {
DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret));
} else
memcpy(dhd->mac.octet, iovbuf, ETHER_ADDR_LEN);
}
#endif /* SET_RANDOM_MAC_SOFTAP */
/* Set Country code
* "US" ---> 11 channels, this is default setting.
* "EU" ---> 13 channels
* "JP" ---> 14 channels
*/
strcpy(dhd->country_code, "EU");
if (dhd->country_code[0] != 0) {
if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_COUNTRY,
dhd->country_code, sizeof(dhd->country_code)) < 0) {
@@ -1284,10 +1302,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
}
}
//dhdcdc_query_ioctl(dhd, 0, WLC_GET_COUNTRY,
// dhd->country_code, sizeof(dhd->country_code));
//printk("============>%s: Current country code: %s\n", __func__, dhd->country_code);
/* Set Listen Interval */
bcm_mkiovar("assoc_listen", (char *)&listen_interval, 4, iovbuf, sizeof(iovbuf));
if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0)
DHD_ERROR(("%s assoc_listen failed %d\n", __FUNCTION__, ret));
/* query for 'ver' to get version info from firmware */
memset(buf, 0, sizeof(buf));
ptr = buf;
@@ -1316,6 +1335,58 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
bcm_mkiovar("roam_off", (char *)&dhd_roam, 4, iovbuf, sizeof(iovbuf));
dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
#if defined(SOFTAP)
if (ap_fw_loaded == TRUE) {
dhdcdc_set_ioctl(dhd, 0, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim));
}
#endif
if (dhd_roam == 0)
{
/* set internal roaming roaming parameters */
int roam_scan_period = 30; /* in sec */
int roam_fullscan_period = 120; /* in sec */
int roam_trigger = -85;
int roam_delta = 15;
int band;
int band_temp_set = WLC_BAND_2G;
if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_SCAN_PERIOD, \
(char *)&roam_scan_period, sizeof(roam_scan_period)) < 0)
DHD_ERROR(("%s: roam scan setup failed\n", __FUNCTION__));
bcm_mkiovar("fullroamperiod", (char *)&roam_fullscan_period, \
4, iovbuf, sizeof(iovbuf));
if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, \
iovbuf, sizeof(iovbuf)) < 0)
DHD_ERROR(("%s: roam fullscan setup failed\n", __FUNCTION__));
if (dhdcdc_query_ioctl(dhd, 0, WLC_GET_BAND, \
(char *)&band, sizeof(band)) < 0)
DHD_ERROR(("%s: roam delta setting failed\n", __FUNCTION__));
else {
if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_ALL))
{
/* temp set band to insert new roams values */
if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_BAND, \
(char *)&band_temp_set, sizeof(band_temp_set)) < 0)
DHD_ERROR(("%s: local band seting failed\n", __FUNCTION__));
}
if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_DELTA, \
(char *)&roam_delta, sizeof(roam_delta)) < 0)
DHD_ERROR(("%s: roam delta setting failed\n", __FUNCTION__));
if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_TRIGGER, \
(char *)&roam_trigger, sizeof(roam_trigger)) < 0)
DHD_ERROR(("%s: roam trigger setting failed\n", __FUNCTION__));
/* Restore original band settinngs */
if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_BAND, \
(char *)&band, sizeof(band)) < 0)
DHD_ERROR(("%s: Original band restore failed\n", __FUNCTION__));
}
}
/* Force STA UP */
if (dhd_radio_up)
dhdcdc_set_ioctl(dhd, 0, WLC_UP, (char *)&up, sizeof(up));
@@ -1350,6 +1421,19 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
}
#endif /* PKT_FILTER_SUPPORT */
#if defined(KEEP_ALIVE)
{
/* Set Keep Alive : be sure to use FW with -keepalive */
int res;
if (ap_fw_loaded == FALSE) {
if ((res = dhd_keep_alive_onoff(dhd, 1)) < 0)
DHD_ERROR(("%s set keeplive failed %d\n", \
__FUNCTION__, res));
}
}
#endif
dhd_os_proto_unblock(dhd);
return 0;
@@ -1375,9 +1459,9 @@ dhd_iscan_allocate_buf(dhd_pub_t *dhd, iscan_buf_t **iscanbuf)
iscanbuf_alloc->next = NULL;
iscanbuf_head = *iscanbuf;
DHD_ISCAN(("%s: addr of allocated node = 0x%X, addr of iscanbuf_head \
= 0x%X dhd = 0x%X\n", __FUNCTION__, iscanbuf_alloc,
iscanbuf_head, dhd));
DHD_ISCAN(("%s: addr of allocated node = 0x%X"
"addr of iscanbuf_head = 0x%X dhd = 0x%X\n",
__FUNCTION__, iscanbuf_alloc, iscanbuf_head, dhd));
if (iscanbuf_head == NULL) {
*iscanbuf = iscanbuf_alloc;
@@ -1404,7 +1488,7 @@ dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete)
dhd_pub_t *dhd = dhd_bus_pub(dhdp);
dhd_iscan_lock();
/* If iscan_delete is null then delete the entire
/* If iscan_delete is null then delete the entire
* chain or else delete specific one provided
*/
if (!iscan_delete) {
@@ -1538,10 +1622,10 @@ dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip)
break;
if (!memcmp(bi->BSSID.octet, addr, ETHER_ADDR_LEN)) {
DHD_ISCAN(("%s: Del BSS[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n", \
__FUNCTION__, l, i, bi->BSSID.octet[0], \
bi->BSSID.octet[1], bi->BSSID.octet[2], \
bi->BSSID.octet[3], bi->BSSID.octet[4], \
DHD_ISCAN(("%s: Del BSS[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n",
__FUNCTION__, l, i, bi->BSSID.octet[0],
bi->BSSID.octet[1], bi->BSSID.octet[2],
bi->BSSID.octet[3], bi->BSSID.octet[4],
bi->BSSID.octet[5]));
bi_new = bi;
@@ -1558,8 +1642,8 @@ dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip)
for (j = i; j < results->count; j++) {
if (bi && bi_new) {
DHD_ISCAN(("%s: Moved up BSS[%2.2d:%2.2d] \
%X:%X:%X:%X:%X:%X\n",
DHD_ISCAN(("%s: Moved up BSS[%2.2d:%2.2d]"
"%X:%X:%X:%X:%X:%X\n",
__FUNCTION__, l, j, bi->BSSID.octet[0],
bi->BSSID.octet[1], bi->BSSID.octet[2],
bi->BSSID.octet[3], bi->BSSID.octet[4],
@@ -1735,17 +1819,274 @@ fail:
return status;
}
#endif
#endif
/* Function to estimate possible DTIM_SKIP value */
int dhd_get_dtim_skip(dhd_pub_t *dhd)
{
int bcn_li_dtim;
char buf[128];
int ret;
int dtim_assoc = 0;
if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1))
bcn_li_dtim = 3;
else
bcn_li_dtim = dhd->dtim_skip;
/* Read DTIM value if associated */
memset(buf, 0, sizeof(buf));
bcm_mkiovar("dtim_assoc", 0, 0, buf, sizeof(buf));
if ((ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf))) < 0) {
DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
bcn_li_dtim = 1;
goto exit;
}
else
dtim_assoc = dtoh32(*(int *)buf);
DHD_ERROR(("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n", \
__FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL));
/* if not assocated just eixt */
if (dtim_assoc == 0) {
goto exit;
}
/* check if sta listen interval fits into AP dtim */
if (dtim_assoc > LISTEN_INTERVAL) {
/* AP DTIM to big for our Listen Interval : no dtim skiping */
bcn_li_dtim = 1;
DHD_ERROR(("%s DTIM=%d > Listen=%d : too big ...\n", \
__FUNCTION__, dtim_assoc, LISTEN_INTERVAL));
goto exit;
}
if ((bcn_li_dtim * dtim_assoc) > LISTEN_INTERVAL) {
/* Round up dtim_skip to fit into STAs Listen Interval */
bcn_li_dtim = (int)(LISTEN_INTERVAL / dtim_assoc);
DHD_TRACE(("%s agjust dtim_skip as %d\n", __FUNCTION__, bcn_li_dtim));
}
exit:
return bcn_li_dtim;
}
#ifdef PNO_SUPPORT
int dhd_pno_clean(dhd_pub_t *dhd)
{
char iovbuf[128];
int pfn_enabled = 0;
int iov_len = 0;
int ret;
/* Disable pfn */
iov_len = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf));
if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) >= 0) {
/* clear pfn */
iov_len = bcm_mkiovar("pfnclear", 0, 0, iovbuf, sizeof(iovbuf));
if (iov_len) {
if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0) {
DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
}
}
else {
ret = -1;
DHD_ERROR(("%s failed code %d\n", __FUNCTION__, iov_len));
}
}
else
DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
return ret;
}
int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
{
char iovbuf[128];
int ret = -1;
if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) {
DHD_ERROR(("%s error exit\n", __FUNCTION__));
return ret;
}
/* Enable/disable PNO */
if ((ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf))) > 0) {
if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) {
DHD_ERROR(("%s failed for error=%d\n", __FUNCTION__, ret));
return ret;
}
else {
dhd->pno_enable = pfn_enabled;
DHD_TRACE(("%s set pno as %d\n", __FUNCTION__, dhd->pno_enable));
}
}
else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, ret));
return ret;
}
/* Function to execute combined scan */
int
dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr)
{
int err = -1;
char iovbuf[128];
int k, i;
wl_pfn_param_t pfn_param;
wl_pfn_t pfn_element;
DHD_TRACE(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, scan_fr));
if ((!dhd) && (!ssids_local)) {
DHD_ERROR(("%s error exit\n", __FUNCTION__));
err = -1;
}
/* Check for broadcast ssid */
for (k = 0; k < nssid; k++) {
if (!ssids_local[k].SSID_len) {
DHD_ERROR(("%d: Broadcast SSID is ilegal for PNO setting\n", k));
return err;
}
}
/* #define PNO_DUMP 1 */
#ifdef PNO_DUMP
{
int j;
for (j = 0; j < nssid; j++) {
DHD_ERROR(("%d: scan for %s size =%d\n", j,
ssids_local[j].SSID, ssids_local[j].SSID_len));
}
}
#endif /* PNO_DUMP */
/* clean up everything */
if ((err = dhd_pno_clean(dhd)) < 0) {
DHD_ERROR(("%s failed error=%d\n", __FUNCTION__, err));
return err;
}
memset(&pfn_param, 0, sizeof(pfn_param));
memset(&pfn_element, 0, sizeof(pfn_element));
/* set pfn parameters */
pfn_param.version = htod32(PFN_VERSION);
pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT));
/* set up pno scan fr */
if (scan_fr != 0)
pfn_param.scan_freq = htod32(scan_fr);
if (pfn_param.scan_freq > PNO_SCAN_MAX_FW) {
DHD_ERROR(("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW));
return err;
}
bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf));
dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
/* set all pfn ssid */
for (i = 0; i < nssid; i++) {
pfn_element.bss_type = htod32(DOT11_BSSTYPE_INFRASTRUCTURE);
pfn_element.auth = (DOT11_OPEN_SYSTEM);
pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY);
pfn_element.wsec = htod32(0);
pfn_element.infra = htod32(1);
memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, ssids_local[i].SSID_len);
pfn_element.ssid.SSID_len = ssids_local[i].SSID_len;
if ((err =
bcm_mkiovar("pfn_add", (char *)&pfn_element,
sizeof(pfn_element), iovbuf, sizeof(iovbuf))) > 0) {
if ((err =
dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) {
DHD_ERROR(("%s failed for i=%d error=%d\n",
__FUNCTION__, i, err));
return err;
}
else
DHD_ERROR(("%s set OK with PNO time=%d\n", __FUNCTION__, \
pfn_param.scan_freq));
}
else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, err));
}
/* Enable PNO */
/* dhd_pno_enable(dhd, 1); */
return err;
}
int dhd_pno_get_status(dhd_pub_t *dhd)
{
int ret = -1;
if (!dhd)
return ret;
else
return (dhd->pno_enable);
}
#endif /* PNO_SUPPORT */
#if defined(KEEP_ALIVE)
int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on)
{
char buf[256];
char *buf_ptr = buf;
wl_keep_alive_pkt_t keep_alive_pkt;
char * str;
int str_len, buf_len;
int res = 0;
int keep_alive_period = KEEP_ALIVE_PERIOD; /* in ms */
DHD_TRACE(("%s: ka:%d\n", __FUNCTION__, ka_on));
if (ka_on) { /* on suspend */
keep_alive_pkt.period_msec = keep_alive_period;
} else {
/* on resume, turn off keep_alive packets */
keep_alive_pkt.period_msec = 0;
}
/* IOC var name */
str = "keep_alive";
str_len = strlen(str);
strncpy(buf, str, str_len);
buf[str_len] = '\0';
buf_len = str_len + 1;
/* set ptr to IOCTL payload after the var name */
buf_ptr += buf_len; /* include term Z */
/* copy Keep-alive attributes from local var keep_alive_pkt */
str = NULL_PKT_STR;
keep_alive_pkt.len_bytes = strlen(str);
memcpy(buf_ptr, &keep_alive_pkt, WL_KEEP_ALIVE_FIXED_LEN);
buf_ptr += WL_KEEP_ALIVE_FIXED_LEN;
/* copy packet data */
memcpy(buf_ptr, str, keep_alive_pkt.len_bytes);
buf_len += (WL_KEEP_ALIVE_FIXED_LEN + keep_alive_pkt.len_bytes);
res = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len);
return res;
}
#endif /* defined(KEEP_ALIVE) */
/* Android ComboSCAN support */
#if defined(CSCAN)
/* Androd ComboSCAN support */
/*
* data parsing from ComboScan tlv list
*/
int
wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token, \
int input_size, int *bytes_left)
wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token,
int input_size, int *bytes_left)
{
char* str = *list_str;
uint16 short_temp;
@@ -1761,8 +2102,8 @@ wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token,
while (*bytes_left > 0) {
if (str[0] != token) {
DHD_TRACE(("%s NOT Type=%d get=%d left_parse=%d \n", __FUNCTION__, \
token, str[0], *bytes_left));
DHD_TRACE(("%s NOT Type=%d get=%d left_parse=%d \n",
__FUNCTION__, token, str[0], *bytes_left));
return -1;
}
@@ -1773,11 +2114,11 @@ wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token,
memcpy(dst, str, input_size);
}
else if (input_size == 2) {
memcpy(dst, (char *)htod16(memcpy(&short_temp, str, input_size)), \
input_size);
memcpy(dst, (char *)htod16(memcpy(&short_temp, str, input_size)),
input_size);
}
else if (input_size == 4) {
memcpy(dst, (char *)htod32(memcpy(&int_temp, str, input_size)), \
memcpy(dst, (char *)htod32(memcpy(&int_temp, str, input_size)),
input_size);
}
@@ -1793,8 +2134,8 @@ wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token,
* channel list parsing from cscan tlv list
*/
int
wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, \
int channel_num, int *bytes_left)
wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list,
int channel_num, int *bytes_left)
{
char* str = *list_str;
int idx = 0;
@@ -1879,7 +2220,7 @@ wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes
/* Get SSID */
if (ssid[idx].SSID_len > *bytes_left) {
DHD_ERROR(("%s out of memory range len=%d but left=%d\n", \
DHD_ERROR(("%s out of memory range len=%d but left=%d\n",
__FUNCTION__, ssid[idx].SSID_len, *bytes_left));
return -1;
}
@@ -1889,8 +2230,8 @@ wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes
*bytes_left -= ssid[idx].SSID_len;
str += ssid[idx].SSID_len;
DHD_TRACE(("%s :size=%d left=%d\n", (char*)ssid[idx].SSID, \
ssid[idx].SSID_len, *bytes_left));
DHD_TRACE(("%s :size=%d left=%d\n",
(char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left));
}
else {
DHD_ERROR(("### SSID size more that %d\n", str[0]));
@@ -1987,4 +2328,4 @@ wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num)
return num;
}
#endif
#endif

View File

@@ -20,7 +20,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: dhd_custom_gpio.c,v 1.1.4.7 2010/06/03 21:27:48 Exp $
* $Id: dhd_custom_gpio.c,v 1.1.4.8.4.1 2010/09/02 23:13:16 Exp $
*/
@@ -34,9 +34,8 @@
#include <wlioctl.h>
#include <wl_iw.h>
#include <dhd_dbg.h>
#define WL_ERROR(x) DHD_ERROR(x)
#define WL_ERROR(x) printf x
#define WL_TRACE(x)
#ifdef CUSTOMER_HW
@@ -47,6 +46,7 @@ extern void bcm_wlan_power_on(int);
int wifi_set_carddetect(int on);
int wifi_set_power(int on, unsigned long msec);
int wifi_get_irq_number(unsigned long *irq_flags_ptr);
int wifi_get_mac_addr(unsigned char *buf);
#endif
#if defined(OOB_INTR_ONLY)
@@ -78,7 +78,7 @@ int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr)
dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM;
}
#endif
*irq_flags_ptr = IRQF_TRIGGER_FALLING;
if (dhd_oob_gpio_num < 0) {
WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined \n",
__FUNCTION__));
@@ -143,9 +143,9 @@ dhd_customer_gpio_wlan_ctrl(int onoff)
__FUNCTION__));
#ifdef CUSTOMER_HW
bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */
/* Lets customer power to get stable */
OSL_DELAY(500);
OSL_DELAY(50);
#endif /* CUSTOMER_HW */
break;
}
}
@@ -155,11 +155,16 @@ dhd_customer_gpio_wlan_ctrl(int onoff)
int
dhd_custom_get_mac_address(unsigned char *buf)
{
int ret = 0;
WL_TRACE(("%s Enter\n", __FUNCTION__));
if (!buf)
return -EINVAL;
/* Customer access to MAC address stored outside of DHD driver */
#ifdef CUSTOMER_HW2
ret = wifi_get_mac_addr(buf);
#endif
#ifdef EXAMPLE_GET_MAC
/* EXAMPLE code */
@@ -169,6 +174,6 @@ dhd_custom_get_mac_address(unsigned char *buf)
}
#endif /* EXAMPLE_GET_MAC */
return 0;
return ret;
}
#endif /* GET_CUSTOM_MAC_ENABLE */

View File

@@ -27,7 +27,7 @@
#ifndef _dhd_dbg_
#define _dhd_dbg_
#if 0 || (defined DHD_DEBUG)
#ifdef DHD_DEBUG
#define DHD_ERROR(args) do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
printf args;} while (0)
@@ -58,7 +58,7 @@
#define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL)
#define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL)
#else /* (defined BCMDBG) || (defined DHD_DEBUG) */
#else /* DHD_DEBUG */
#define DHD_ERROR(args) do {if (net_ratelimit()) printf args;} while (0)
#define DHD_TRACE(args)
@@ -87,7 +87,7 @@
#define DHD_EVENT_ON() 0
#define DHD_BTA_ON() 0
#define DHD_ISCAN_ON() 0
#endif
#endif /* DHD_DEBUG */
#define DHD_LOG(args)

File diff suppressed because it is too large Load Diff

View File

@@ -34,7 +34,7 @@
#include <wlioctl.h>
#ifndef IOCTL_RESP_TIMEOUT
#define IOCTL_RESP_TIMEOUT 2000 /* In milli second */
#define IOCTL_RESP_TIMEOUT 3000 /* In milli second */
#endif
#ifndef IOCTL_CHIP_ACTIVE_TIMEOUT

View File

@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: dhd_sdio.c,v 1.157.2.27.2.33.2.126 2010/06/15 23:38:39 Exp $
* $Id: dhd_sdio.c,v 1.157.2.27.2.33.2.129.4.1 2010/09/02 23:13:16 Exp $
*/
#include <typedefs.h>
@@ -36,17 +36,11 @@
#include <bcmutils.h>
#include <bcmendian.h>
#include <bcmdevs.h>
#include <siutils.h>
#include <hndpmu.h>
#include <hndsoc.h>
#ifdef DHD_DEBUG
#include <hndrte_armtrap.h>
#include <hndrte_cons.h>
#endif /* DHD_DEBUG */
#include <sbchipc.h>
#include <sbhnddma.h>
#include <sdio.h>
#include <sbsdio.h>
#include <sbsdpcmdev.h>
@@ -64,9 +58,12 @@
#include <dhdioctl.h>
#include <sdiovar.h>
#ifndef DHDSDIO_MEM_DUMP_FNAME
#define DHDSDIO_MEM_DUMP_FNAME "mem_dump"
#endif
#ifdef DHD_DEBUG
#include <hndrte_cons.h>
#endif /* DHD_DEBUG */
#ifdef DHD_DEBUG_TRAP
#include <hndrte_armtrap.h>
#endif /* DHD_DEBUG_TRAP */
#define QLEN 256 /* bulk rx and tx queue lengths */
#define FCHI (QLEN - 10)
@@ -127,11 +124,11 @@
/* Bump up limit on waiting for HT to account for first startup;
* if the image is doing a CRC calculation before programming the PMU
* for HT availability, it could take a couple hundred ms more, so
* max out at a half second (500000us).
* max out at a 1 second (1000000us).
*/
#if (PMU_MAX_TRANSITION_DLY <= 500000)
#if (PMU_MAX_TRANSITION_DLY < 1000000)
#undef PMU_MAX_TRANSITION_DLY
#define PMU_MAX_TRANSITION_DLY 500000
#define PMU_MAX_TRANSITION_DLY 1000000
#endif
/* Value for ChipClockCSR during initial setup */
@@ -149,6 +146,8 @@
DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep);
extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len);
extern void bcmsdh_set_irq(int flag);
#ifdef DHD_DEBUG
/* Device console log buffer state */
typedef struct dhd_console {
@@ -427,10 +426,10 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq);
static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start);
#endif
#ifdef DHD_DEBUG
#ifdef DHD_DEBUG_TRAP
static int dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size);
static int dhdsdio_mem_dump(dhd_bus_t *bus);
#endif /* DHD_DEBUG */
#endif /* DHD_DEBUG_TRAP */
static int dhdsdio_download_state(dhd_bus_t *bus, bool enter);
static void dhdsdio_release(dhd_bus_t *bus, osl_t *osh);
@@ -441,7 +440,7 @@ static bool dhdsdio_probe_attach(dhd_bus_t *bus, osl_t *osh, void *sdh,
void * regsva, uint16 devid);
static bool dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh);
static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh);
static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh);
static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, int reset_flag);
static uint process_nvram_vars(char *varbuf, uint len);
@@ -551,7 +550,6 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok)
bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err);
DHD_INFO(("CLKCTL: set PENDING\n"));
bus->clkstate = CLK_PENDING;
return BCME_OK;
} else if (bus->clkstate == CLK_PENDING) {
/* Cancel CA-only interrupt filter */
@@ -722,7 +720,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
bus->activity = TRUE;
}
return BCME_OK;
return ret;
}
switch (target) {
@@ -747,9 +745,8 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
else
DHD_ERROR(("dhdsdio_clkctl: request for %d -> %d\n",
bus->clkstate, target));
if (ret == BCME_OK) {
if (ret == BCME_OK)
dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
}
break;
case CLK_NONE:
@@ -1303,7 +1300,6 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen)
bus->ctrl_frame_stat = FALSE;
ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
frame, len, NULL, NULL, NULL);
ASSERT(ret != BCME_PENDING);
if (ret < 0) {
@@ -1377,21 +1373,21 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
__FUNCTION__, rxlen, msglen));
} else if (timeleft == 0) {
DHD_ERROR(("%s: resumed on timeout\n", __FUNCTION__));
#ifdef DHD_DEBUG
#ifdef DHD_DEBUG_TRAP
dhd_os_sdlock(bus->dhd);
dhdsdio_checkdied(bus, NULL, 0);
dhd_os_sdunlock(bus->dhd);
#endif /* DHD_DEBUG */
#endif /* DHD_DEBUG_TRAP */
} else if (pending == TRUE) {
DHD_CTL(("%s: cancelled\n", __FUNCTION__));
return -ERESTARTSYS;
} else {
DHD_CTL(("%s: resumed for unknown reason?\n", __FUNCTION__));
#ifdef DHD_DEBUG
#ifdef DHD_DEBUG_TRAP
dhd_os_sdlock(bus->dhd);
dhdsdio_checkdied(bus, NULL, 0);
dhd_os_sdunlock(bus->dhd);
#endif /* DHD_DEBUG */
#endif /* DHD_DEBUG_TRAP */
}
if (rxlen)
@@ -1411,7 +1407,7 @@ enum {
IOV_SDCIS,
IOV_MEMBYTES,
IOV_MEMSIZE,
#ifdef DHD_DEBUG
#ifdef DHD_DEBUG_TRAP
IOV_CHECKDIED,
#endif
IOV_DOWNLOAD,
@@ -1464,10 +1460,10 @@ const bcm_iovar_t dhdsdio_iovars[] = {
{"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0 },
{"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0 },
{"cpu", IOV_CPU, 0, IOVT_BOOL, 0 },
#ifdef DHD_DEBUG
{"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0 },
#endif /* DHD_DEBUG */
#endif /* DHD_DEBUG */
#ifdef DHD_DEBUG_TRAP
{"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0 },
#endif /* DHD_DEBUG_TRAP */
#ifdef SDTEST
{"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0 },
{"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t) },
@@ -1696,7 +1692,7 @@ xfer_done:
return bcmerror;
}
#ifdef DHD_DEBUG
#ifdef DHD_DEBUG_TRAP
static int
dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh)
{
@@ -1849,12 +1845,10 @@ dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size)
DHD_ERROR(("%s: %s\n", __FUNCTION__, strbuf.origbuf));
}
#ifdef DHD_DEBUG
if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
/* Mem dump to a file on device */
dhdsdio_mem_dump(bus);
/* Mem dump to a file on device */
dhdsdio_mem_dump(bus);
}
#endif /* DHD_DEBUG */
done:
if (mbuffer)
@@ -1905,17 +1899,22 @@ dhdsdio_mem_dump(dhd_bus_t *bus)
}
printf("Done\n");
#ifdef DHD_DEBUG
/* free buf before return !!! */
if (write_to_file(bus->dhd, buf, bus->ramsize))
{
printf("%s: Error writing to files\n", __FUNCTION__);
return -1;
}
/* buf free handled in write_to_file, not here */
#else
MFREE(bus->dhd->osh, buf, size);
#endif
return 0;
}
#endif /* DHD_DEBUG_TRAP */
#ifdef DHD_DEBUG
#define CONSOLE_LINE_MAX 192
static int
@@ -2726,6 +2725,9 @@ dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
BUS_WAKE(bus);
/* Change our idea of bus state */
bus->dhd->busstate = DHD_BUS_DOWN;
/* Enable clock for device interrupts */
dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
@@ -2734,9 +2736,6 @@ dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
local_hostintmask = bus->hostintmask;
bus->hostintmask = 0;
/* Change our idea of bus state */
bus->dhd->busstate = DHD_BUS_DOWN;
/* Force clocks on backplane to be sure F2 interrupt propagates */
saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
if (!err) {
@@ -2789,23 +2788,24 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
dhd_timeout_t tmo;
uint retries = 0;
uint8 ready, enable;
int err, ret = 0;
int err, ret = BCME_ERROR;
uint8 saveclk;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
ASSERT(bus->dhd);
if (!bus->dhd)
return 0;
return BCME_OK;
if (enforce_mutex)
dhd_os_sdlock(bus->dhd);
/* Make sure backplane clock is on, needed to generate F2 interrupt */
dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
if (bus->clkstate != CLK_AVAIL)
err = dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
if ((err != BCME_OK) || (bus->clkstate != CLK_AVAIL)) {
DHD_ERROR(("%s: Failed to set backplane clock: err %d\n", __FUNCTION__, err));
goto exit;
}
/* Force clocks on backplane to be sure F2 interrupt propagates */
saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
@@ -2880,6 +2880,7 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
if (dhdp->busstate != DHD_BUS_DATA)
dhdsdio_clkctl(bus, CLK_NONE, FALSE);
ret = BCME_OK;
exit:
if (enforce_mutex)
dhd_os_sdunlock(bus->dhd);
@@ -4233,6 +4234,9 @@ clkwait:
DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n",
__FUNCTION__, rxdone, framecnt));
bus->intdis = FALSE;
#if defined(OOB_INTR_ONLY)
bcmsdh_oob_intr_set(1);
#endif /* (OOB_INTR_ONLY) */
bcmsdh_intr_enable(sdh);
}
@@ -4367,13 +4371,14 @@ dhdsdio_isr(void *arg)
#if defined(SDIO_ISR_THREAD)
DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __FUNCTION__));
dhd_os_wake_lock(bus->dhd);
while (dhdsdio_dpc(bus));
dhd_os_wake_unlock(bus->dhd);
#else
bus->dpc_sched = TRUE;
dhd_sched_dpc(bus->dhd);
#endif
}
#ifdef SDTEST
@@ -4634,8 +4639,6 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
if (bus->sleeping)
return FALSE;
dhd_os_sdlock(bus->dhd);
/* Poll period: check device if appropriate. */
if (bus->poll && (++bus->polltick >= bus->pollrate)) {
uint32 intstatus = 0;
@@ -4700,15 +4703,11 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
bus->idlecount = 0;
if (bus->activity) {
bus->activity = FALSE;
dhd_os_wd_timer(bus->dhd,dhd_watchdog_ms);
} else {
dhdsdio_clkctl(bus, CLK_NONE, FALSE);
}
}
}
dhd_os_sdunlock(bus->dhd);
return bus->ipend;
}
@@ -4960,12 +4959,15 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
/* if firmware path present try to download and bring up bus */
if ((ret = dhd_bus_start(bus->dhd)) != 0) {
#if 1
DHD_ERROR(("%s: failed\n", __FUNCTION__));
goto fail;
#else
if (ret == BCME_NOTUP) {
DHD_ERROR(("%s: dongle is not responding\n", __FUNCTION__));
goto fail;
}
#endif
}
/* Ok, have the per-port tell the stack we're open for business */
if (dhd_net_attach(bus->dhd, 0) != 0) {
@@ -5266,7 +5268,6 @@ dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh,
ret = dhdsdio_download_firmware(bus, osh, bus->sdh);
return ret;
}
@@ -5276,12 +5277,13 @@ dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh)
bool ret;
/* Download the firmware */
dhd_os_wake_lock(bus->dhd);
dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
ret = _dhdsdio_download_firmware(bus) == 0;
dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
dhd_os_wake_unlock(bus->dhd);
return ret;
}
@@ -5301,7 +5303,7 @@ dhdsdio_release(dhd_bus_t *bus, osl_t *osh)
if (bus->dhd) {
dhdsdio_release_dongle(bus, osh);
dhdsdio_release_dongle(bus, osh, TRUE);
dhd_detach(bus->dhd);
bus->dhd = NULL;
@@ -5345,11 +5347,11 @@ dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh)
static void
dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh)
dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, int reset_flag)
{
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
if (bus->dhd && bus->dhd->dongle_reset)
if ((bus->dhd && bus->dhd->dongle_reset) && reset_flag)
return;
if (bus->sih) {
@@ -5799,24 +5801,25 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
if (flag == TRUE) {
if (!bus->dhd->dongle_reset) {
dhd_os_sdlock(dhdp);
/* Turning off watchdog */
dhd_os_wd_timer(dhdp, 0);
#if !defined(IGNORE_ETH0_DOWN)
/* Force flow control as protection when stop come before ifconfig_down */
dhd_txflowcontrol(bus->dhd, 0, ON);
#endif /* !defined(IGNORE_ETH0_DOWN) */
/* save country settinng if was pre-setup with priv ioctl */
dhd_os_proto_block(dhdp);
dhdcdc_query_ioctl(bus->dhd, 0, WLC_GET_COUNTRY,
bus->dhd->country_code, sizeof(bus->dhd->country_code));
dhd_os_proto_unblock(dhdp);
/* Expect app to have torn down any connection before calling */
/* Stop the bus, disable F2 */
dhd_bus_stop(bus, FALSE);
#if defined(OOB_INTR_ONLY)
bcmsdh_set_irq(FALSE);
#endif /* defined(OOB_INTR_ONLY) */
/* Clean tx/rx buffer pointers, detach from the dongle */
dhdsdio_release_dongle(bus, bus->dhd->osh);
dhdsdio_release_dongle(bus, bus->dhd->osh, TRUE);
bus->dhd->dongle_reset = TRUE;
bus->dhd->up = FALSE;
dhd_os_sdunlock(dhdp);
DHD_TRACE(("%s: WLAN OFF DONE\n", __FUNCTION__));
/* App can now remove power from device */
@@ -5829,6 +5832,8 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
if (bus->dhd->dongle_reset) {
/* Turn on WLAN */
dhd_os_sdlock(dhdp);
/* Reset SD client */
bcmsdh_reset(bus->sdh);
@@ -5841,25 +5846,32 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
dhdsdio_download_firmware(bus, bus->dhd->osh, bus->sdh)) {
/* Re-init bus, enable F2 transfer */
dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE);
bcmerror = dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE);
if (bcmerror == BCME_OK) {
#if defined(OOB_INTR_ONLY)
dhd_enable_oob_intr(bus, TRUE);
bcmsdh_set_irq(TRUE);
dhd_enable_oob_intr(bus, TRUE);
#endif /* defined(OOB_INTR_ONLY) */
bus->dhd->dongle_reset = FALSE;
bus->dhd->up = TRUE;
bus->dhd->dongle_reset = FALSE;
bus->dhd->up = TRUE;
#if !defined(IGNORE_ETH0_DOWN)
/* Restore flow control */
dhd_txflowcontrol(bus->dhd, 0, OFF);
#endif
/* Restore flow control */
dhd_txflowcontrol(bus->dhd, 0, OFF);
#endif
/* Turning on watchdog back */
dhd_os_wd_timer(dhdp, dhd_watchdog_ms);
DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__));
DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__));
} else {
dhd_bus_stop(bus, FALSE);
dhdsdio_release_dongle(bus, bus->dhd->osh, FALSE);
}
} else
bcmerror = BCME_SDIO_ERROR;
} else
bcmerror = BCME_SDIO_ERROR;
dhd_os_sdunlock(dhdp);
} else {
bcmerror = BCME_NOTDOWN;
DHD_ERROR(("%s: Set DEVRESET=FALSE invoked when device is on\n",

View File

@@ -1,49 +0,0 @@
# bcm94319wlusbn4l board
# $Copyright (C) 2008 Broadcom Corporation$
# $Id: bcm94319lcsdn4l.txt,v 1.18 2009/11/11 17:44:06 jayaramn Exp $
sromrev=3
vendid=0x14e4
devid=0x4338
boardtype=0x507
boardrev=0x1402
boardflags=0x02000200
# On board crystal frequency in KHz
xtalfreq=30000
aa2g=1
aa5g=0
ag0=3
ccode=ww
regrev=5
opo=0
pa0b0=0x15E0
pa0b1=0xFAC6
pa0b2=0xFEC3
pa0itssit=62
pa0maxpwr=74
rssismf2g=0xa
rssismc2g=0xb
rssisav2g=0x3
bxa2g=0
tri2g=0x6B
cckdigfilttype=3
rxpo2g=2
cckpo=0
ofdmpo=0x44444444
mcs2gpo0=0x6666
mcs2gpo1=0x6666
mcs2gpo2=0x0000
mcs2gpo3=0x0000
mcs2gpo4=0x6666
mcs2gpo5=0x6666
boardnum=1
macaddr=00:90:4c:14:43:19
#for mfgc
otpimagesize=182

View File

@@ -29,7 +29,6 @@
#define STATIC static
#define SI_BUS 0
#define PCI_BUS 1
#define PCMCIA_BUS 2

View File

@@ -28,7 +28,7 @@
#define __BCMSDH_SDMMC_H__
#define sd_err(x)
#define sd_trace(x)
#define sd_trace(x)
#define sd_info(x)
#define sd_debug(x)
#define sd_data(x)

View File

@@ -0,0 +1,134 @@
/*
* SD-SPI Protocol Conversion - BCMSDH->gSPI Translation Layer
*
* Copyright (C) 2010, Broadcom Corporation
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
* the contents of this file may not be disclosed to third parties, copied
* or duplicated in any form, in whole or in part, without the prior
* written permission of Broadcom Corporation.
*
* $Id: bcmspibrcm.h,v 1.4.4.1.4.3.6.1 2008/09/27 17:03:25 Exp $
*/
/* global msglevel for debug messages - bitvals come from sdiovar.h */
#define sd_err(x)
#define sd_trace(x)
#define sd_info(x)
#define sd_debug(x)
#define sd_data(x)
#define sd_ctrl(x)
#define sd_log(x)
#define SDIOH_ASSERT(exp) \
do { if (!(exp)) \
printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \
} while (0)
#define BLOCK_SIZE_F1 64
#define BLOCK_SIZE_F2 2048
#define BLOCK_SIZE_F3 2048
/* internal return code */
#define SUCCESS 0
#undef ERROR
#define ERROR 1
#define ERROR_UF 2
#define ERROR_OF 3
/* private bus modes */
#define SDIOH_MODE_SPI 0
#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */
#define USE_MULTIBLOCK 0x4
struct sdioh_info {
uint cfg_bar; /* pci cfg address for bar */
uint32 caps; /* cached value of capabilities reg */
void *bar0; /* BAR0 for PCI Device */
osl_t *osh; /* osh handler */
void *controller; /* Pointer to SPI Controller's private data struct */
uint lockcount; /* nest count of spi_lock() calls */
bool client_intr_enabled; /* interrupt connnected flag */
bool intr_handler_valid; /* client driver interrupt handler valid */
sdioh_cb_fn_t intr_handler; /* registered interrupt handler */
void *intr_handler_arg; /* argument to call interrupt handler */
bool initialized; /* card initialized */
uint32 target_dev; /* Target device ID */
uint32 intmask; /* Current active interrupts */
void *sdos_info; /* Pointer to per-OS private data */
uint32 controller_type; /* Host controller type */
uint8 version; /* Host Controller Spec Compliance Version */
uint irq; /* Client irq */
uint32 intrcount; /* Client interrupts */
uint32 local_intrcount; /* Controller interrupts */
bool host_init_done; /* Controller initted */
bool card_init_done; /* Client SDIO interface initted */
bool polled_mode; /* polling for command completion */
bool sd_use_dma; /* DMA on CMD53 */
bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */
/* Must be on for sd_multiblock to be effective */
bool use_client_ints; /* If this is false, make sure to restore */
/* polling hack in wl_linux.c:wl_timer() */
int adapter_slot; /* Maybe dealing with multiple slots/controllers */
int sd_mode; /* SD1/SD4/SPI */
int client_block_size[SPI_MAX_IOFUNCS]; /* Blocksize */
uint32 data_xfer_count; /* Current transfer */
uint16 card_rca; /* Current Address */
uint8 num_funcs; /* Supported funcs on client */
uint32 card_dstatus; /* 32bit device status */
uint32 com_cis_ptr;
uint32 func_cis_ptr[SPI_MAX_IOFUNCS];
void *dma_buf;
ulong dma_phys;
int r_cnt; /* rx count */
int t_cnt; /* tx_count */
uint32 wordlen; /* host processor 16/32bits */
uint32 prev_fun;
uint32 chip;
uint32 chiprev;
bool resp_delay_all;
bool dwordmode;
struct spierrstats_t spierrstats;
};
/************************************************************
* Internal interfaces: per-port references into bcmspibrcm.c
*/
/* Global message bits */
extern uint sd_msglevel;
/**************************************************************
* Internal interfaces: bcmspibrcm.c references to per-port code
*/
/* Interrupt (de)registration routines */
extern int spi_register_irq(sdioh_info_t *sd, uint irq);
extern void spi_free_irq(uint irq, sdioh_info_t *sd);
/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */
extern void spi_lock(sdioh_info_t *sd);
extern void spi_unlock(sdioh_info_t *sd);
/* Allocate/init/free per-OS private data */
extern int spi_osinit(sdioh_info_t *sd);
extern void spi_osfree(sdioh_info_t *sd);
#define SPI_RW_FLAG_M BITFIELD_MASK(1) /* Bit [31] - R/W Command Bit */
#define SPI_RW_FLAG_S 31
#define SPI_ACCESS_M BITFIELD_MASK(1) /* Bit [30] - Fixed/Incr Access */
#define SPI_ACCESS_S 30
#define SPI_FUNCTION_M BITFIELD_MASK(2) /* Bit [29:28] - Function Number */
#define SPI_FUNCTION_S 28
#define SPI_REG_ADDR_M BITFIELD_MASK(17) /* Bit [27:11] - Address */
#define SPI_REG_ADDR_S 11
#define SPI_LEN_M BITFIELD_MASK(11) /* Bit [10:0] - Packet length */
#define SPI_LEN_S 0

View File

@@ -31,18 +31,18 @@
#define EPI_MINOR_VERSION 218
#define EPI_RC_NUMBER 245
#define EPI_RC_NUMBER 248
#define EPI_INCREMENTAL_NUMBER 0
#define EPI_INCREMENTAL_NUMBER 18
#define EPI_BUILD_NUMBER 0
#define EPI_VERSION 4, 218, 245, 0
#define EPI_VERSION 4, 218, 248, 18
#define EPI_VERSION_NUM 0x04daf500
#define EPI_VERSION_NUM 0x04daf812
#define EPI_VERSION_STR "4.218.245.0"
#define EPI_ROUTER_VERSION_STR "4.219.245.0"
#define EPI_VERSION_STR "4.218.248.18"
#define EPI_ROUTER_VERSION_STR "4.219.248.18"
#endif

View File

@@ -32,13 +32,9 @@
#include <linux/version.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
#include <linux/config.h>
#else
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
#include <generated/autoconf.h>
#else
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))
#include <linux/autoconf.h>
#endif
#endif
#include <linux/module.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0))
@@ -70,6 +66,7 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/semaphore.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
#undef IP_TOS
#endif
@@ -429,22 +426,11 @@ pci_restore_state(struct pci_dev *dev, u32 *buffer)
#define CHECKSUM_HW CHECKSUM_PARTIAL
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
#define KILL_PROC(nr, sig) \
{ \
struct task_struct *tsk; \
struct pid *pid; \
pid = find_get_pid((pid_t)nr); \
tsk = pid_task(pid, PIDTYPE_PID); \
if (tsk) send_sig(sig, tsk, 1); \
}
#else
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \
KERNEL_VERSION(2, 6, 30))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
#define KILL_PROC(pid, sig) \
{ \
struct task_struct *tsk; \
tsk = find_task_by_vpid(pid); \
tsk = pid_task(find_vpid(pid), PIDTYPE_PID); \
if (tsk) send_sig(sig, tsk, 1); \
}
#else
@@ -453,7 +439,6 @@ if (tsk) send_sig(sig, tsk, 1); \
kill_proc(pid, sig, 1); \
}
#endif
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
#define netdev_priv(dev) dev->priv

View File

@@ -24,7 +24,7 @@
*
* Dependencies: proto/bcmeth.h
*
* $Id: bcmevent.h,v 9.34.4.1.20.16 2009/09/25 23:52:38 Exp $
* $Id: bcmevent.h,v 9.34.4.1.20.16.64.1 2010/11/08 21:57:03 Exp $
*
*/
@@ -131,10 +131,10 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event {
#define WLC_E_ACTION_FRAME 58
#define WLC_E_ACTION_FRAME_COMPLETE 59
#define WLC_E_ESCAN_RESULT 69
#define WLC_E_WAKE_EVENT 70
#define WLC_E_LAST 71
#define WLC_E_ESCAN_RESULT 69
#define WLC_E_WAKE_EVENT 70
#define WLC_E_RELOAD 71
#define WLC_E_LAST 72
@@ -205,6 +205,7 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event {
#define WLC_E_IF_ADD 1
#define WLC_E_IF_DEL 2
#define WLC_E_RELOAD_STATUS1 1
#include <packed_section_end.h>

View File

@@ -1001,7 +1001,6 @@ typedef volatile struct {
#define CST4315_CBUCK_MODE_BURST 0x00000400
#define CST4315_CBUCK_MODE_LPBURST 0x00000c00
#define PMU_MAX_TRANSITION_DLY 15000

View File

@@ -0,0 +1,153 @@
/*
* SPI device spec header file
*
* Copyright (C) 2010, Broadcom Corporation
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
* the contents of this file may not be disclosed to third parties, copied
* or duplicated in any form, in whole or in part, without the prior
* written permission of Broadcom Corporation.
*
* $Id: spid.h,v 1.7.10.1.16.3 2009/04/09 19:23:14 Exp $
*/
#ifndef _SPI_H
#define _SPI_H
/*
* Brcm SPI Device Register Map.
*
*/
typedef volatile struct {
uint8 config; /* 0x00, len, endian, clock, speed, polarity, wakeup */
uint8 response_delay; /* 0x01, read response delay in bytes (corerev < 3) */
uint8 status_enable; /* 0x02, status-enable, intr with status, response_delay
* function selection, command/data error check
*/
uint8 reset_bp; /* 0x03, reset on wlan/bt backplane reset (corerev >= 1) */
uint16 intr_reg; /* 0x04, Intr status register */
uint16 intr_en_reg; /* 0x06, Intr mask register */
uint32 status_reg; /* 0x08, RO, Status bits of last spi transfer */
uint16 f1_info_reg; /* 0x0c, RO, enabled, ready for data transfer, blocksize */
uint16 f2_info_reg; /* 0x0e, RO, enabled, ready for data transfer, blocksize */
uint16 f3_info_reg; /* 0x10, RO, enabled, ready for data transfer, blocksize */
uint32 test_read; /* 0x14, RO 0xfeedbead signature */
uint32 test_rw; /* 0x18, RW */
uint8 resp_delay_f0; /* 0x1c, read resp delay bytes for F0 (corerev >= 3) */
uint8 resp_delay_f1; /* 0x1d, read resp delay bytes for F1 (corerev >= 3) */
uint8 resp_delay_f2; /* 0x1e, read resp delay bytes for F2 (corerev >= 3) */
uint8 resp_delay_f3; /* 0x1f, read resp delay bytes for F3 (corerev >= 3) */
} spi_regs_t;
/* SPI device register offsets */
#define SPID_CONFIG 0x00
#define SPID_RESPONSE_DELAY 0x01
#define SPID_STATUS_ENABLE 0x02
#define SPID_RESET_BP 0x03 /* (corerev >= 1) */
#define SPID_INTR_REG 0x04 /* 16 bits - Interrupt status */
#define SPID_INTR_EN_REG 0x06 /* 16 bits - Interrupt mask */
#define SPID_STATUS_REG 0x08 /* 32 bits */
#define SPID_F1_INFO_REG 0x0C /* 16 bits */
#define SPID_F2_INFO_REG 0x0E /* 16 bits */
#define SPID_F3_INFO_REG 0x10 /* 16 bits */
#define SPID_TEST_READ 0x14 /* 32 bits */
#define SPID_TEST_RW 0x18 /* 32 bits */
#define SPID_RESP_DELAY_F0 0x1c /* 8 bits (corerev >= 3) */
#define SPID_RESP_DELAY_F1 0x1d /* 8 bits (corerev >= 3) */
#define SPID_RESP_DELAY_F2 0x1e /* 8 bits (corerev >= 3) */
#define SPID_RESP_DELAY_F3 0x1f /* 8 bits (corerev >= 3) */
/* Bit masks for SPID_CONFIG device register */
#define WORD_LENGTH_32 0x1 /* 0/1 16/32 bit word length */
#define ENDIAN_BIG 0x2 /* 0/1 Little/Big Endian */
#define CLOCK_PHASE 0x4 /* 0/1 clock phase delay */
#define CLOCK_POLARITY 0x8 /* 0/1 Idle state clock polarity is low/high */
#define HIGH_SPEED_MODE 0x10 /* 1/0 High Speed mode / Normal mode */
#define INTR_POLARITY 0x20 /* 1/0 Interrupt active polarity is high/low */
#define WAKE_UP 0x80 /* 0/1 Wake-up command from Host to WLAN */
/* Bit mask for SPID_RESPONSE_DELAY device register */
#define RESPONSE_DELAY_MASK 0xFF /* Configurable rd response delay in multiples of 8 bits */
/* Bit mask for SPID_STATUS_ENABLE device register */
#define STATUS_ENABLE 0x1 /* 1/0 Status sent/not sent to host after read/write */
#define INTR_WITH_STATUS 0x2 /* 0/1 Do-not / do-interrupt if status is sent */
#define RESP_DELAY_ALL 0x4 /* Applicability of resp delay to F1 or all func's read */
#define DWORD_PKT_LEN_EN 0x8 /* Packet len denoted in dwords instead of bytes */
#define CMD_ERR_CHK_EN 0x20 /* Command error check enable */
#define DATA_ERR_CHK_EN 0x40 /* Data error check enable */
/* Bit mask for SPID_RESET_BP device register */
#define RESET_ON_WLAN_BP_RESET 0x4 /* enable reset for WLAN backplane */
#define RESET_ON_BT_BP_RESET 0x8 /* enable reset for BT backplane */
#define RESET_SPI 0x80 /* reset the above enabled logic */
/* Bit mask for SPID_INTR_REG device register */
#define DATA_UNAVAILABLE 0x0001 /* Requested data not available; Clear by writing a "1" */
#define F2_F3_FIFO_RD_UNDERFLOW 0x0002
#define F2_F3_FIFO_WR_OVERFLOW 0x0004
#define COMMAND_ERROR 0x0008 /* Cleared by writing 1 */
#define DATA_ERROR 0x0010 /* Cleared by writing 1 */
#define F2_PACKET_AVAILABLE 0x0020
#define F3_PACKET_AVAILABLE 0x0040
#define F1_OVERFLOW 0x0080 /* Due to last write. Bkplane has pending write requests */
#define MISC_INTR0 0x0100
#define MISC_INTR1 0x0200
#define MISC_INTR2 0x0400
#define MISC_INTR3 0x0800
#define MISC_INTR4 0x1000
#define F1_INTR 0x2000
#define F2_INTR 0x4000
#define F3_INTR 0x8000
/* Bit mask for 32bit SPID_STATUS_REG device register */
#define STATUS_DATA_NOT_AVAILABLE 0x00000001
#define STATUS_UNDERFLOW 0x00000002
#define STATUS_OVERFLOW 0x00000004
#define STATUS_F2_INTR 0x00000008
#define STATUS_F3_INTR 0x00000010
#define STATUS_F2_RX_READY 0x00000020
#define STATUS_F3_RX_READY 0x00000040
#define STATUS_HOST_CMD_DATA_ERR 0x00000080
#define STATUS_F2_PKT_AVAILABLE 0x00000100
#define STATUS_F2_PKT_LEN_MASK 0x000FFE00
#define STATUS_F2_PKT_LEN_SHIFT 9
#define STATUS_F3_PKT_AVAILABLE 0x00100000
#define STATUS_F3_PKT_LEN_MASK 0xFFE00000
#define STATUS_F3_PKT_LEN_SHIFT 21
/* Bit mask for 16 bits SPID_F1_INFO_REG device register */
#define F1_ENABLED 0x0001
#define F1_RDY_FOR_DATA_TRANSFER 0x0002
#define F1_MAX_PKT_SIZE 0x01FC
/* Bit mask for 16 bits SPID_F2_INFO_REG device register */
#define F2_ENABLED 0x0001
#define F2_RDY_FOR_DATA_TRANSFER 0x0002
#define F2_MAX_PKT_SIZE 0x3FFC
/* Bit mask for 16 bits SPID_F3_INFO_REG device register */
#define F3_ENABLED 0x0001
#define F3_RDY_FOR_DATA_TRANSFER 0x0002
#define F3_MAX_PKT_SIZE 0x3FFC
/* Bit mask for 32 bits SPID_TEST_READ device register read in 16bit LE mode */
#define TEST_RO_DATA_32BIT_LE 0xFEEDBEAD
/* Maximum number of I/O funcs */
#define SPI_MAX_IOFUNCS 4
#define SPI_MAX_PKT_LEN (2048*4)
/* Misc defines */
#define SPI_FUNC_0 0
#define SPI_FUNC_1 1
#define SPI_FUNC_2 2
#define SPI_FUNC_3 3
#define WAIT_F2RXFIFORDY 100
#define WAIT_F2RXFIFORDY_DELAY 20
#endif /* _SPI_H */

View File

@@ -0,0 +1,9 @@
#ifndef WIFI_VERSION_H
#define WIFI_VERSION_H
/*
* Broadcom BCM4319 driver version.
*/
#define BCM4319_DRV_VERSION "2.00"
#endif /* WIFI_BCM4319_VERSION_H */

View File

@@ -24,7 +24,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: wlioctl.h,v 1.601.4.15.2.14.2.61 2010/05/04 20:26:25 Exp $
* $Id: wlioctl.h,v 1.601.4.15.2.14.2.62.4.1 2010/11/17 03:09:28 Exp $
*/
@@ -857,6 +857,7 @@ typedef struct wl_ioctl {
#define PM_MAX 1
#define PM_FAST 2
#define LISTEN_INTERVAL 20
#define INTERFERE_NONE 0
#define NON_WLAN 1
@@ -1317,6 +1318,8 @@ enum {
#define PFN_VERSION 1
#define MAX_PFN_LIST_COUNT 16
typedef struct wl_pfn_param {
int32 version;

View File

@@ -26,9 +26,7 @@
#define LINUX_OSL
#if defined(CHROMIUMOS_COMPAT_WIRELESS)
#include <linux/sched.h>
#endif
#include <typedefs.h>
#include <bcmendian.h>
#include <linuxver.h>
@@ -37,6 +35,7 @@
#include <bcmutils.h>
#include <linux/delay.h>
#include <pcicfg.h>
#include <linux/mutex.h>
#define PCI_CFG_RETRY 10
@@ -48,7 +47,7 @@
#define STATIC_BUF_SIZE (PAGE_SIZE*2)
#define STATIC_BUF_TOTAL_LEN (MAX_STATIC_BUF_NUM*STATIC_BUF_SIZE)
typedef struct bcm_static_buf {
struct semaphore static_sem;
struct mutex static_sem;
unsigned char *buf_ptr;
unsigned char buf_use[MAX_STATIC_BUF_NUM];
} bcm_static_buf_t;
@@ -59,7 +58,7 @@ static bcm_static_buf_t *bcm_static_buf = 0;
typedef struct bcm_static_pkt {
struct sk_buff *skb_4k[MAX_STATIC_PKT_NUM];
struct sk_buff *skb_8k[MAX_STATIC_PKT_NUM];
struct semaphore osl_pkt_sem;
struct mutex osl_pkt_sem;
unsigned char pkt_use[MAX_STATIC_PKT_NUM*2];
} bcm_static_pkt_t;
static bcm_static_pkt_t *bcm_static_skb = 0;
@@ -153,8 +152,10 @@ osl_t *
osl_attach(void *pdev, uint bustype, bool pkttag)
{
osl_t *osh;
gfp_t flags;
osh = kmalloc(sizeof(osl_t), GFP_ATOMIC);
flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
osh = kmalloc(sizeof(osl_t), flags);
ASSERT(osh);
bzero(osh, sizeof(osl_t));
@@ -195,11 +196,11 @@ osl_attach(void *pdev, uint bustype, bool pkttag)
STATIC_BUF_TOTAL_LEN))) {
printk("can not alloc static buf!\n");
}
else
printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf);
else {
/* printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); */
}
init_MUTEX(&bcm_static_buf->static_sem);
mutex_init(&bcm_static_buf->static_sem);
bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE;
@@ -217,7 +218,7 @@ osl_attach(void *pdev, uint bustype, bool pkttag)
for (i = 0; i < MAX_STATIC_PKT_NUM*2; i++)
bcm_static_skb->pkt_use[i] = 0;
init_MUTEX(&bcm_static_skb->osl_pkt_sem);
mutex_init(&bcm_static_skb->osl_pkt_sem);
}
#endif
return osh;
@@ -304,7 +305,7 @@ osl_pktget_static(osl_t *osh, uint len)
}
down(&bcm_static_skb->osl_pkt_sem);
mutex_lock(&bcm_static_skb->osl_pkt_sem);
if (len <= PAGE_SIZE)
{
@@ -317,7 +318,7 @@ osl_pktget_static(osl_t *osh, uint len)
if (i != MAX_STATIC_PKT_NUM)
{
bcm_static_skb->pkt_use[i] = 1;
up(&bcm_static_skb->osl_pkt_sem);
mutex_unlock(&bcm_static_skb->osl_pkt_sem);
skb = bcm_static_skb->skb_4k[i];
skb->tail = skb->data + len;
@@ -337,7 +338,7 @@ osl_pktget_static(osl_t *osh, uint len)
if (i != MAX_STATIC_PKT_NUM)
{
bcm_static_skb->pkt_use[i+MAX_STATIC_PKT_NUM] = 1;
up(&bcm_static_skb->osl_pkt_sem);
mutex_unlock(&bcm_static_skb->osl_pkt_sem);
skb = bcm_static_skb->skb_8k[i];
skb->tail = skb->data + len;
skb->len = len;
@@ -347,7 +348,7 @@ osl_pktget_static(osl_t *osh, uint len)
up(&bcm_static_skb->osl_pkt_sem);
mutex_unlock(&bcm_static_skb->osl_pkt_sem);
printk("all static pkt in use!\n");
return osl_pktget(osh, len);
}
@@ -362,9 +363,9 @@ osl_pktfree_static(osl_t *osh, void *p, bool send)
{
if (p == bcm_static_skb->skb_4k[i])
{
down(&bcm_static_skb->osl_pkt_sem);
mutex_lock(&bcm_static_skb->osl_pkt_sem);
bcm_static_skb->pkt_use[i] = 0;
up(&bcm_static_skb->osl_pkt_sem);
mutex_unlock(&bcm_static_skb->osl_pkt_sem);
return;
@@ -455,8 +456,8 @@ void*
osl_malloc(osl_t *osh, uint size)
{
void *addr;
gfp_t flags;
if (osh)
ASSERT(osh->magic == OS_HANDLE_MAGIC);
@@ -466,7 +467,7 @@ osl_malloc(osl_t *osh, uint size)
int i = 0;
if ((size >= PAGE_SIZE)&&(size <= STATIC_BUF_SIZE))
{
down(&bcm_static_buf->static_sem);
mutex_lock(&bcm_static_buf->static_sem);
for (i = 0; i < MAX_STATIC_BUF_NUM; i++)
{
@@ -476,13 +477,13 @@ osl_malloc(osl_t *osh, uint size)
if (i == MAX_STATIC_BUF_NUM)
{
up(&bcm_static_buf->static_sem);
mutex_unlock(&bcm_static_buf->static_sem);
printk("all static buff in use!\n");
goto original;
}
bcm_static_buf->buf_use[i] = 1;
up(&bcm_static_buf->static_sem);
mutex_unlock(&bcm_static_buf->static_sem);
bzero(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i, size);
if (osh)
@@ -493,8 +494,8 @@ osl_malloc(osl_t *osh, uint size)
}
original:
#endif
if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) {
flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
if ((addr = kmalloc(size, flags)) == NULL) {
if (osh)
osh->failed++;
return (NULL);
@@ -518,9 +519,9 @@ osl_mfree(osl_t *osh, void *addr, uint size)
buf_idx = ((unsigned char *)addr - bcm_static_buf->buf_ptr)/STATIC_BUF_SIZE;
down(&bcm_static_buf->static_sem);
mutex_lock(&bcm_static_buf->static_sem);
bcm_static_buf->buf_use[buf_idx] = 0;
up(&bcm_static_buf->static_sem);
mutex_unlock(&bcm_static_buf->static_sem);
if (osh) {
ASSERT(osh->magic == OS_HANDLE_MAGIC);
@@ -606,8 +607,10 @@ void *
osl_pktdup(osl_t *osh, void *skb)
{
void * p;
gfp_t flags;
if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL)
flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
if ((p = skb_clone((struct sk_buff*)skb, flags)) == NULL)
return NULL;

View File

@@ -1,13 +0,0 @@
rm -f *.o
rm -f ../wifi_power/*.o
rm -f *.uu
rm -rf bcm4319
rm -f .*.cmd
rm -f ../wifi_power/.*.cmd
rm -f modules.order Module.symvers
find . -name '*.o' -exec rm -f {} \;
find . -name '.*.cmd' -exec rm -f {} \;

View File

@@ -1,27 +0,0 @@
#!/bin/sh
echo "Begin to make BCM4319 wifi driver package ..."
RKWLCFGDIR=../wifi_power
PKGNAME="bcm4319"
RKPUB="rkpub"
PKGVER=`grep -r '#define BCM4319_DRV_VERSION' ${RKWLCFGDIR}/wifi_version.h | sed 's/[^"]*\"\([0-9A-Za-z\.]*\)*\"/\1/'`
[ `dirname $0` = '.' ] || exit
rm -rf ${RKPUB}
mkdir -p ${RKPUB}/${PKGNAME}
cp Makefile.${PKGNAME} ${RKPUB}/${PKGNAME}/Makefile
cp Kconfig.${PKGNAME} ${RKPUB}/${PKGNAME}/Kconfig
cp ${RKWLCFGDIR}/wifi_power.c ${RKPUB}/${PKGNAME}/wifi_power.c
cp ${RKWLCFGDIR}/wifi_power.h ${RKPUB}/${PKGNAME}/wifi_power.h
cp ${RKWLCFGDIR}/wifi_version.h ${RKPUB}/${PKGNAME}/wifi_version.h
chmod 644 ${RKPUB}/${PKGNAME}/*
cp -dpR firmware ${RKPUB}/${PKGNAME}/
find ${RKPUB}/${PKGNAME}/firmware -type d -name '.svn' | xargs rm -rf
uuencode ${PKGNAME}.o ${PKGNAME}.o > ${RKPUB}/${PKGNAME}/${PKGNAME}.uu
cd ${RKPUB} && tar -jcvf ${PKGNAME}-${PKGVER}.tar.bz2 ${PKGNAME}
echo "Done"

View File

@@ -3165,8 +3165,8 @@ wl_get_iscan_results(struct wl_iscan_ctrl *iscan, uint32 *status, struct wl_scan
results->buflen = dtoh32(results->buflen);
results->version = dtoh32(results->version);
results->count = dtoh32(results->count);
//WL_DBG(("results->count = %d\n", results->count));
//WL_DBG(("results->buflen = %d\n", results->buflen));
WL_DBG(("results->count = %d\n", results->count));
WL_DBG(("results->buflen = %d\n", results->buflen));
*status = dtoh32(list_buf->status);
*bss_list = results;

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
* $Id: wl_iw.h,v 1.5.34.1.6.24 2010/07/27 20:46:02 Exp $
* $Id: wl_iw.h,v 1.5.34.1.6.36.4.15 2010/11/17 03:13:51 Exp $
*/
@@ -43,27 +43,42 @@
#define GET_HOME_DWELL "HOME="
#define GET_SCAN_TYPE "TYPE="
#define BAND_GET_CMD "BANDGET"
#define BAND_SET_CMD "BANDSET"
#define BAND_GET_CMD "GETBAND"
#define BAND_SET_CMD "SETBAND"
#define DTIM_SKIP_GET_CMD "DTIMSKIPGET"
#define DTIM_SKIP_SET_CMD "DTIMSKIPSET"
#define SETSUSPEND_CMD "SETSUSPENDOPT"
#define PNOSSIDCLR_SET_CMD "PNOSSIDCLR"
#define PNOSETUP_SET_CMD "PNOSETUP "
#define PNOENABLE_SET_CMD "PNOFORCE"
#define PNODEBUG_SET_CMD "PNODEBUG"
#define SETDFSCHANNELS_CMD "SETDFSCHANNELS"
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#define WL_IW_RSSI_MINVAL -200
#define WL_IW_RSSI_NO_SIGNAL -91
#define WL_IW_RSSI_VERY_LOW -80
#define WL_IW_RSSI_LOW -70
#define WL_IW_RSSI_GOOD -68
#define WL_IW_RSSI_VERY_GOOD -58
#define WL_IW_RSSI_EXCELLENT -57
#define WL_IW_RSSI_INVALID 0
#define MAX_WX_STRING 80
#define isprint(c) bcm_isprint(c)
typedef struct wl_iw_extra_params {
int target_channel;
} wl_iw_extra_params_t;
#define WL_IW_RSSI_MINVAL -200
#define WL_IW_RSSI_NO_SIGNAL -91
#define WL_IW_RSSI_VERY_LOW -80
#define WL_IW_RSSI_LOW -70
#define WL_IW_RSSI_GOOD -68
#define WL_IW_RSSI_VERY_GOOD -58
#define WL_IW_RSSI_EXCELLENT -57
#define WL_IW_RSSI_INVALID 0
#define MAX_WX_STRING 80
#define isprint(c) bcm_isprint(c)
#define WL_IW_SET_ACTIVE_SCAN (SIOCIWFIRSTPRIV+1)
#define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3)
#define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3)
#define WL_IW_SET_PASSIVE_SCAN (SIOCIWFIRSTPRIV+5)
#define WL_IW_GET_LINK_SPEED (SIOCIWFIRSTPRIV+7)
#define WL_IW_GET_CURR_MACADDR (SIOCIWFIRSTPRIV+9)
#define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11)
#define WL_IW_SET_START (SIOCIWFIRSTPRIV+13)
#define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11)
#define WL_IW_SET_START (SIOCIWFIRSTPRIV+13)
#define WL_SET_AP_CFG (SIOCIWFIRSTPRIV+15)
@@ -73,12 +88,13 @@
#define AP_LPB_CMD (SIOCIWFIRSTPRIV+23)
#define WL_AP_STOP (SIOCIWFIRSTPRIV+25)
#define WL_FW_RELOAD (SIOCIWFIRSTPRIV+27)
#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+29)
#define WL_AP_SPARE3 (SIOCIWFIRSTPRIV+31)
#define G_SCAN_RESULTS 8*1024
#define WE_ADD_EVENT_FIX 0x80
#define G_WLAN_SET_ON 0
#define G_WLAN_SET_OFF 1
#define WL_AP_STA_DISASSOC (SIOCIWFIRSTPRIV+29)
#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+31)
#define G_SCAN_RESULTS (8*1024)
#define WE_ADD_EVENT_FIX 0x80
#define G_WLAN_SET_ON 0
#define G_WLAN_SET_OFF 1
#define CHECK_EXTRA_FOR_NULL(extra) \
if (!extra) { \
@@ -92,9 +108,9 @@ typedef struct wl_iw {
struct iw_statistics wstats;
int spy_num;
uint32 pwsec;
uint32 gwsec;
bool privacy_invoked;
uint32 pwsec;
uint32 gwsec;
bool privacy_invoked;
struct ether_addr spy_addr[IW_MAX_SPY];
struct iw_quality spy_qual[IW_MAX_SPY];
@@ -102,18 +118,17 @@ typedef struct wl_iw {
dhd_pub_t * pub;
} wl_iw_t;
int wl_control_wl_start(struct net_device *dev);
#define WLC_IW_SS_CACHE_MAXLEN 512
#define WLC_IW_SS_CACHE_MAXLEN 2048
#define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN 32
#define WLC_IW_BSS_INFO_MAXLEN \
(WLC_IW_SS_CACHE_MAXLEN - WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN)
typedef struct wl_iw_ss_cache {
struct wl_iw_ss_cache *next;
int dirty;
uint32 buflen;
uint32 version;
uint32 count;
int dirty;
wl_bss_info_t bss_info[1];
} wl_iw_ss_cache_t;
@@ -126,6 +141,7 @@ typedef struct wl_iw_ss_cache_ctrl {
uint m_cons_br_scan_cnt;
struct timer_list *m_timer;
} wl_iw_ss_cache_ctrl_t;
typedef enum broadcast_first_scan {
BROADCAST_SCAN_FIRST_IDLE = 0,
BROADCAST_SCAN_FIRST_STARTED,
@@ -141,36 +157,51 @@ struct ap_profile {
uint8 ssid[SSID_LEN];
uint8 sec[SEC_LEN];
uint8 key[KEY_LEN];
uint32 channel;
uint32 channel;
uint32 preamble;
uint32 max_scb;
uint32 max_scb;
uint32 closednet;
char country_code[WLC_CNTRY_BUF_SZ];
};
#define MACLIST_MODE_DISABLED 0
#define MACLIST_MODE_ENABLED 1
#define MACLIST_MODE_DENY 1
#define MACLIST_MODE_ALLOW 2
struct mflist {
uint count;
struct ether_addr ea[16];
};
struct mac_list_set {
uint32 mode;
struct mflist white_list;
struct mflist black_list;
struct mflist mac_list;
};
#endif
#endif
#if WIRELESS_EXT > 12
#include <net/iw_handler.h>
extern const struct iw_handler_def wl_iw_handler_def;
#endif
#endif
extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data);
extern int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats);
int wl_iw_attach(struct net_device *dev, void * dhdp);
void wl_iw_detach(void);
int wl_control_wl_start(struct net_device *dev);
extern int net_os_wake_lock(struct net_device *dev);
extern int net_os_wake_unlock(struct net_device *dev);
extern int net_os_wake_lock_timeout(struct net_device *dev);
extern int net_os_wake_lock_timeout_enable(struct net_device *dev);
extern int net_os_set_suspend_disable(struct net_device *dev, int val);
extern int net_os_set_suspend(struct net_device *dev, int val);
extern int net_os_set_dtim_skip(struct net_device *dev, int val);
extern int net_os_set_packet_filter(struct net_device *dev, int val);
extern void dhd_bus_country_set(struct net_device *dev, char *country_code);
extern char *dhd_bus_country_get(struct net_device *dev);
extern int dhd_get_dtim_skip(dhd_pub_t *dhd);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \
@@ -188,6 +219,32 @@ void wl_iw_detach(void);
iwe_stream_add_point(stream, ends, iwe, extra)
#endif
extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
extern int dhd_pno_clean(dhd_pub_t *dhd);
extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr);
extern int dhd_pno_get_status(dhd_pub_t *dhd);
extern int dhd_dev_pno_reset(struct net_device *dev);
extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, \
int nssid, ushort scan_fr);
extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled);
extern int dhd_dev_get_pno_status(struct net_device *dev);
#define PNO_TLV_PREFIX 'S'
#define PNO_TLV_VERSION '1'
#define PNO_TLV_SUBVERSION '2'
#define PNO_TLV_RESERVED '0'
#define PNO_TLV_TYPE_SSID_IE 'S'
#define PNO_TLV_TYPE_TIME 'T'
#define PNO_EVENT_UP "PNO_EVENT"
#define PNO_SCAN_MAX_FW 508
typedef struct cmd_tlv {
char prefix;
char version;
char subver;
char reserved;
} cmd_tlv_t;
#if defined(CSCAN)
typedef struct cscan_tlv {
@@ -201,13 +258,13 @@ typedef struct cscan_tlv {
#define CSCAN_TLV_PREFIX 'S'
#define CSCAN_TLV_VERSION 1
#define CSCAN_TLV_SUBVERSION 0
#define CSCAN_TLV_TYPE_SSID_IE 'S'
#define CSCAN_TLV_TYPE_CHANNEL_IE 'C'
#define CSCAN_TLV_TYPE_NPROBE_IE 'N'
#define CSCAN_TLV_TYPE_ACTIVE_IE 'A'
#define CSCAN_TLV_TYPE_PASSIVE_IE 'P'
#define CSCAN_TLV_TYPE_HOME_IE 'H'
#define CSCAN_TLV_TYPE_STYPE_IE 'T'
#define CSCAN_TLV_TYPE_SSID_IE 'S'
#define CSCAN_TLV_TYPE_CHANNEL_IE 'C'
#define CSCAN_TLV_TYPE_NPROBE_IE 'N'
#define CSCAN_TLV_TYPE_ACTIVE_IE 'A'
#define CSCAN_TLV_TYPE_PASSIVE_IE 'P'
#define CSCAN_TLV_TYPE_HOME_IE 'H'
#define CSCAN_TLV_TYPE_STYPE_IE 'T'
extern int wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, \
int channel_num, int *bytes_left);

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,9 @@
config RTL8192CU
tristate "Realtek 8192C USB WiFi"
depends on USB
select WIRELESS_EXT
select WEXT_PRIV
select IEEE80211
---help---
Help message of RTL8192CU

View File

@@ -1,170 +1,169 @@
begin 644 core/rtw_ioctl_set.o
M?T5,1@$!`0````````````$`*``!``````````````!<$```````!30`````
M?T5,1@$!`0````````````$`*``!``````````````!4$```````!30`````
M`"@`$``-``1`+>4`()#E(`!2XQ0``(H``%+C%```"@0PT.4@,$/B<S#OYEX`
M4^,`0*"3!!"@DP8``)H*``#J!#"`X`$PT^<@,$/B<S#OYEX`4^,$``"*`4"$
MXG1`[^8$`%+A]?__B@$``.H`0*#C````Z@%`H.,$`*#A$`"]Z![_+^$00"WI
M`#"@X00@D>4-$=+C$P``&@$#$N,'```:!CN`X@0P@^(#(`+B`@*#X``0H.,0
M(*#C_O__ZPD``.I7#8#B$`"`XN`0@^+^___K`$!0X@,```H1#H3B`!"@XQ`@
MH./^___K`0"@XQ"`O>CP02WI`4"@X0%@H.$`4*#A`0!PX@``H#.A#Y#A%0``
M&@,`4>,3``"*7GV%XBP`A^(!`H#@`!"@XQ`@H./^___K!0"@X2`0A^($(*#A
M`#"@X_[__^M?3H3B"D"$X@1!A>`$0(3B`#"@XP`PA.4#0%#@`4"@$P```.H`
M0*#C!`"@X?"!O>AP0"WI`$"@X0%0H.$$8)'E`V'&XP0`5N,`0*##(0``R@@P
MD>4%`%/C`2"@`Z0W`0,#((0'!@``"@T`4^,`(*`3I#<!$P,@A!<%(*`#I#<!
M`P,@A`<&`H3@7@V`XBP`@.(,$(7B"""5Y?[__^M?/H;B"C"#X@,QA.`(()7E
M!""#Y:@W`>,#8(3G!`"@X5X=A.(@$('B!B"@X0$PH./^___K`$!0X@%`H!,$
M`*#A<("]Z/!'+>D(T$WB`$"@X0%0H.$$,)'E``!3XP(``+H!`1/C+@``"D(!
M`.H!`1/C*P``"E<-@.(0`(#BX!"$XO[__^L`8%#B!```"J`W`>,#,)3G`@!3
MX^Q@E@4!```*I#<!XP-@E.<$,-7E``!3XS`!`!H,,)7E`0!SXS$!`!JP(=7A
M_S\/XP,`4N$M`0`:*`$`Z@@PE>4@`%/C)0$`&DP``.H$`%;C"0``&@@PE>40
M`%/C!@``"B``4^,=`0`:$#"@XP@PA>4`<*#C!X"@X40``.H%`%;C`0!6$Q4!
M``H\``#J"#L!XP,PE.<#`%/C$P``BOPW`>,#,)3G``!3XP\``!H(,)7E!0!3
MXP$@H`.D-P$#`R"$!P8```H-`%/C`""@$Z0W`1,#((07!2"@`Z0W`0,#((0'
MI#<!XP-@E.<!``#J_#<!XP-@E.=L,)3E(``3XP8```H,,)7E`0!SX_0``!JP
M(=7A_S\/XP,`4N'P```:`@!6XP,``!H(,)7E(`!3X^L``!H(``#J!`!6XP8`
M`!H(,)7E$`!3XR``4Q/D```:(`!3XQ`PH`,(,(4%!'"5Y==]X.=L,)3E(``3
MXP<```H!`!/C`7"@$P>`H!$#```*`P``Z@!PH.,'@*#A````Z@&`H..@-P'C
M`S"4YP(`4^,E```*!0!6XP$`5A,B```:"""5Y2`@@N*(/@'C`R"$YP1@E>4"
M8<;CC#X!XP-@A.<(()7ED#X!XP,@A.<@<(7B>HV$XA0`B.('$*#A"""5Y?[_
M_^L&`H3@7@V`XBP`@.('$*#A"""5Y?[__^M?/H;B"C"#X@,QA.`(()7E!""#
MY:@W`>,#8(3G!`"@X0@0B.+^___K`4"@XZH``.H$,)7E`@(3XQL```H!`%CC
M#```&M@!Q>$`(.#C_S\/XP`@`N`!,`/@"!"-XO@@8>%C#83B$`"`X@T0H.$(
M(*#C_O__ZPX``.K8`<7A`"#@X_\_#^,`(`+@`3`#X`@0C>+X(&'A8PV$X@@`
M@.(-$*#A"""@X_[__^M0``#J`0!8XTX``!H!`%?C!"#5!08[H`,#((0'!#"5
MY0,`$^.!```*!FN$X@1@AN(#,`/B`P*&X``0H.,0(*#C_O__ZV%]A.($<(?B
M!`#5Y0,``.(``H?@`!"@XQ`@H./^___K8HV$X@2`B.($`-7E`P``X@`"B.``
M$*#C$""@X_[__^L$,)7E`0(3XPL```H#,`/B`P*'X#`0A>(((*#C_O__ZP0`
MU>4#``#B``*(X#@0A>(((*#C_O__ZPH``.H#,`/B`P*'X#@0A>(((*#C_O__
MZP0`U>4#``#B``*(X#`0A>(((*#C_O__ZP0`U>4#``#B``*&X"`0A>((()7E
M_O__ZP0PE>4#,`/B!#"%Y0$PH./X*@'C`C#$YP`0H./Z*@'C`A#$YP0`H.%>
M'83B(!"!X@0@E>7^___K`$!0X@%`H!,Z``#J5PV$XA``@.+@$(3B_O__ZP"`
M4.(!0*`#,P``"A&NB.(*`*#A`!"@XQ`@H./^___K()"%X@H`H.$)$*#A$""@
MX_[__^L"`%;C%@``&@`@H./Y.@'C`R#$YP0PE>4!`A/C"```"O``B.(0$(GB
M"""@X_[__^L!#(CB&!")X@@@H./^___K!P``ZO``B.(8$(GB"""@X_[__^L!
M#(CB$!")X@@@H./^___K``!7XP4```H$`*#A"!"@X0`@H./^___K`$"@X00`
M`.H$`*#A"!"@X0$@H./^___K`$"@X0!`5.(!0*`3````Z@!`H.,$`*#A"-"-
MXO"'O>@"`%;CU/[_&L_^_^H00"WI7DV`XB!`A.((.P'C`Q"`YP,`4>,"(*"#
MH#<!@P,@@(<$$*#A_O__ZP$`4.,``*`3`0"@`Q"`O>AP0"WI*-!-X@!`4.(>
M```*=34#XP,PU.<``%/C&@``"FPPE.4B#1/C&0``&@PUU.4!`%/C%@``"O[_
M_^L-,*#A?VW#XS]@QN,$,);E`3"#X@0PAN4$4(WB!0"@X0`0H.,D(*#C_O__
MZP0`H.$%$*#A_O__ZP!`H.$$,);E`3!#X@0PAN7^___K`@``Z@!`H.,```#J
M`4"@XP0`H.$HT(WB<("]Z!!`+>D`0*#A_O__ZPT@H.%_/<+C/S##XP0@D^4!
M((+B!""#Y6PPE.4!`!/C!0``"@0`H.'^___K!`"@X?[__^L$`*#A_O__ZPT@
MH.%_/<+C/S##XP0@D^4!($+B!""#Y?[__^L!`*#C$("]Z'!`+>D`0*#A`5"@
MX3@QD.4!`%/A/@``"O[__^L-(*#A?SW"XS\PP^,$()/E`2""X@0@@^5L,)3E
M`0`3XP(``!HX(93E``!2XP0``!H$`*#A_O__ZVPPE.4!`!/C`0``&D``$^,$
M```*!`"@X?[__^ML,)3E`0`3XP0``!HX,93E`0!3XP$```H``%/C`0``&@0`
MH.'^___K.#&4Y00`4^,#```:`##@X]@PA.4$`*#A_O__ZSA1A.5L,)3E>###
MXVPPA.4!`%7C"#"#`VPPA`4(```*(#"#,VPPA#4%```Z!`!5XP,``!H0,(/C
M;#"$Y00`H.'^___K#2"@X7\]PN,_,,/C!""3Y0$@0N($((/E_O__ZP$`H.-P
M@+WH<$`MZ0!`H.&$4)#E`3#@X]@P@.5L,)#E@#"#XVPP@.5X4(#E`3"@XW`P
MP.6$`(#B_O__ZP$`4.,-```:;#"4Y8`PP^-L,(3E##74Y0``4^,"```*<3#4
MY0``4^,\```*!`"@X900A.+^___K`$"@X3@``.IL`(3B_O__ZP$`4.,+```:
M`#"@XW`PQ.4`,`#C`#!`XP`0D^5%#H3B"`"`XJ(?@>("$('B_O__ZP%`H.,H
M``#J;#"4Y2``$^,7```*0#"@XVPPA.6I;83B)5"&X@4`H.$`$*#C)""@X_[_
M_^L%`*#AE!"$XB0@H./^___K!`"@X?[__^L=`(;B_O__ZP0`H.'^___K`0!0
MXP!`H!,`,*`#<##$!0%`H`,-``#J@###XVPPA.4,-=3E``!3XP(```IQ,-3E
M``!3XP0```H$`*#AE!"$XO[__^L`0*#A````Z@%`H.,$`*#A<("]Z/!!+>D`
M4*#A`7"@X74U`^,#,-#G``!3XP!`H`-O```*;#"0Y8``$^,!0*`3:P``&@(+
M$^-K```:$```ZFPPE>4""Q/C!0``"@8`H.'^___K`4!$X@$`=./W__\:`0``
MZ@``5.,%``#*C`&?Y8P1G^7^___K;$"5Y=1#X.=0``#J_O__ZPT@H.%_/<+C
M/S##XP0@D^4!((+B!""#Y6PPE>5!`!/C,P``"I0@E>4`,)?E`P!2X2$``!J8
M`(7B!!"'XO[__^L!`%#C'```&FPPE>4(`!/C%```&@4`H.'`$(7B_O__ZP``
M4.,!0*`3-```&@4`H.'^___K;#"5Y0$`$^,!```*!0"@X?[__^L%`*#A_O__
MZVPPE>5``!/C0###$R`P@Q-L,(45$@``Z@4`H.$!$*#C`2"@X?[__^L-``#J
M!0"@X?[__^ML,)7E`0`3XP$```H%`*#A_O__ZP4`H.'^___K;#"5Y4``$^-`
M,,,3(#"#$VPPA14F/*#C`S#5YP$`4^,-```*!P"@X?[__^L``%#C"0``"I0`
MA>('$*#A)""@X_[__^L`,*#CB#2%Y04`H.'^___K`$"@X0```.H`0*#C#2"@
MX7\]PN,_,,/C!""3Y0$@0N($((/E_O__ZP0`H.'P@;WH9`"@X_[__^LP0*#C
M9&"@XX___^H``````````'!`+>D`0*#A`5"@X0`PT>4``%/C#P``&@$@T>4`
M`%+C#```&@(PT>4``%/C&@``&@,PT>4``%/C%P``&@0PT>4``%/C%```&@4P
MT>4``%/C$0``&D<``.K_`%/C#@``&@$PU>7_`%/C"P``&@(PU>7_`%/C"```
M&@,PU>7_`%/C!0``&@0PU>7_`%/C`@``&@4PU>7_`%/C-@``"O[__^L-(*#A
M?SW"XS\PP^,$()/E`2""X@0@@^5L,)3E(@T3X]-#X!<C```:00`3XQ@```K@
M`(3B!1"@X08@H./^___K`0!0XP0``!IL,)3E"``3XP%`H`,7```*#0``Z@0`
MH.'^___K;#"4Y0$`$^,!```*!`"@X?[__^L$`*#A_O__ZVPPE.5``!/C0###
M$R`P@Q-L,(05N`"$X@40H.$&(*#C_O__ZP$PH..(-(3E!`"@X?[__^L`0*#A
M#2"@X7\]PN,_,,/C!""3Y0$@0N($((/E_O__ZP```.H`0*#C!`"@X7"`O>@`
M````L+"@@'P```"PL*B`Z````+"PK(!L`0``L+"J@!P"``"PK@&`;`<``+"P
MJ("H!P``L*H)@$P(``"PL*B`N`@``+"PJH#4"0``L+"J@#0+``"PL*R`.`T`
M`+"PJH!R='=?<V5T7S@P,E\Q,5]S<VED`"5S.B!3970@4U-)1"!I<R!N;W0@
M86QL;W=E9"!U;F1E<B!S=7)V97EI;F<*``````!'0T,Z("A'3E4I(#0N-"XP
M`$$J````865A8FD``2`````%-RU!``8*!T$(`1($%`$5`1<#&`$9`1H"'@$`
M+G-Y;71A8@`N<W1R=&%B`"YS:'-T<G1A8@`N<F5L+G1E>'0`+F1A=&$`+F)S
M<P`N05)-+F5X=&%B`"YR96PN05)-+F5X:61X`"YR;V1A=&$`+G)O9&%T82YS
M='(Q+C0`+F-O;6UE;G0`+FYO=&4N1TY5+7-T86-K`"Y!4DTN871T<FEB=71E
M<P```````````````````````````````````````````````````````!\`
M```!````!@`````````T````O`X`````````````!``````````;````"0``
M````````````$!H``+@"```.`````0````0````(````)0````$````#````
M`````/`.```````````````````!`````````"L````(`````P````````#P
M#@```````````````````0`````````P`````0````(`````````\`X`````
M``````````````$`````````/P````$``'""`````````/`.``!@`````0``
M```````$`````````#L````)``````````````#('```:`````X````&````
M!`````@```!*`````0````(`````````4`\``!0```````````````0`````
M````4@````$````R`````````&0/```P```````````````$`````0```&$`
M```!``````````````"4#P``$@```````````````0````````!J`````0``
M````````````I@\```````````````````$`````````>@````,``'``````
M`````*8/```K```````````````!`````````!$````#``````````````#1
M#P``B@```````````````0`````````!`````@``````````````W!(``!`$
M```/````&@````0````0````"0````,``````````````.P6```C`P``````
M```````!```````````````````````````````!```````````````$`/'_
M`````````````````P`!``````````````````,``P`````````````````#
M``0`$0`````````````````!``````````````````,`!0``````````````
M```#``8`$0```'P````````````!`!$```#H`````````````0`1````;`$`
M``````````$`$0```!P"```````````!`!$```!L!P```````````0`1````
MJ`<```````````$`$0```$P(```````````!`!$```"X"````````````0`1
M````U`D```````````$`$0```#0+```````````!`!0````P#0``````````
M`0`1````.`T```````````$``````````````````P`(`!<`````````%```
M``$`"``````````````````#``D``````````````````P`+````````````
M``````,`"@`````````````````#``P`)@````````!\````$@`!`#@`````
M`````````!````!/````?````&P````2``$`:0``````````````$````'4`
M`````````````!````"%````Z````(0````2``$`GP``````````````$```
M`*L```!L`0``L````!(``0#"```````````````0````S@```!P"``!0!0``
M$@`!`.4``````````````!````#W````;`<``#P````2``$`&@$`````````
M````$````"<!``"H!P``I````!(``0!&`0`````````````0````5P$`````
M````````$````&H!`````````````!````!Z`0``3`@``&P````2``$`E@$`
M````````````$````*<!`````````````!````"_`0`````````````0````
MV`$``+@(```<`0``$@`!`/L!`````````````!`````(`@`````````````0
M````%@(``-0)``!@`0``$@`!`"("`````````````!`````S`@``````````
M```0````6@(`````````````$````&("`````````````!````!L`@``````
M```````0````D`(`````````````$````*D"`````````````!````"[`@``
M-`L```0"```2``$`SP(`````````````$````-8"`````````````!````#=
M`@`````````````0````Z0(`````````````$````/H"`````````````!``
M```.`P``.`T``(0!```2``$``')T=U]I;V-T;%]S970N8P`D80`D9`!?7V9U
M;F-?7RXS-#8V-0!R='=?=F%L:61A=&5?<W-I9`!?7V%E86)I7W5N=VEN9%]C
M<'!?<'(P`')T=U]S971?.#`R7S$Q7W)E;6]V95]K97D`7W)T=U]M96US970`
M<G1W7V=E=%]S=&%I;F9O`')T=U]S971?.#`R7S$Q7W)E;6]V95]W97``<G1W
M7W-E=%]K97D`<G1W7W-E=%\X,#)?,3%?861D7W=E<`!?<G1W7VUE;6-P>0!R
M='=?<V5T7S@P,E\Q,5]A9&1?:V5Y`')T=U]S971S=&%K97E?8VUD`')T=U]S
M971?.#`R7S$Q7V%U=&AE;G1I8V%T:6]N7VUO9&4`<G1W7W-E=%]A=71H`')T
M=U]S971?.#`R7S$Q7V)S<VED7VQI<W1?<V-A;@!L;V-A;%]B:%]D:7-A8FQE
M`')T=U]S:71E<W5R=F5Y7V-M9`!L;V-A;%]B:%]E;F%B;&4`<G1W7W-E=%\X
M,#)?,3%?9&ES87-S;V-I871E`')T=U]D:7-A<W-O8U]C;60`<G1W7VEN9&EC
M871E7V1I<V-O;FYE8W0`<G1W7V9R965?87-S;V-?<F5S;W5R8V5S`')T=U]S
M971?.#`R7S$Q7VEN9G)A<W1R=6-T=7)E7VUO9&4`<W1O<%]A<%]M;V1E`'-T
M87)T7V%P7VUO9&4`<G1W7V1O7VIO:6X`7W)T=U]Q=65U95]E;7!T>0!R='=?
M<V5L96-T7V%N9%]J;VEN7V9R;VU?<V-A;FYE9%]Q=65U90!J:69F:65S`&UO
M9%]T:6UE<@!R='=?=7!D871E7W)E9VES=')Y<')I=E]D979?;F5T=V]R:P!R
M='=?9V5N97)A=&5?<F%N9&]M7VEB<W,`<G1W7V-R96%T96)S<U]C;60`<G1W
M7W-E=%\X,#)?,3%?<W-I9`!M<VQE97``<')I;G1K`%]R='=?;65M8VUP`')T
M=U]I<U]S86UE7VEB<W,`<G1W7VQP<U]C=')L7W=K7V-M9`!R='=?<V5T7S@P
M,E\Q,5]B<W-I9```L````!P=``#$````'!X``-P````<'0``)`$``!P=```X
M`0``'"```-0!```<(@``"`(``!P@``!8`@``'!X``%P$```<(@``=`0``!PB
M``"<!```'"$``.@$```<(@``'`4``!PB``!@!0``'!T``(`%```<'0``H`4`
M`!P=``#`!0``'"(``-@%```<(@``\`4``!PB```(!@``'"(``"`&```<(@``
M6`8``!P@``!T!@``'!X``)0&```<'0``J`8``!PB``#8!@``'"(``.@&```<
M(@``_`8``!PB```,!P``'"(``"0'```<)```/`<``!PD``"4!P``'"8``.`'
M```<*```#`@``!P=```8"```'"D``"P(```<*@``5`@``!PH``"`"```'"P`
M`(@(```<+0``D`@``!PN``"L"```'"H``-`(```<*```"`D``!PL```D"0``
M'"X``$P)```<+0``:`D``!PP``"L"0``'#$``,@)```<*@``!`H``!PS```\
M"@``'"D``$P*```<-```8`H``"LU``!D"@``+#4``'P*```<-@``L`H``!P=
M``#`"@``'"(``,@*```<-P``T`H``!PX``#8"@``'#D``!P+```<*0``@`L`
M`!P[``"D"P``'#P``+0+```<*```]`L``!P]```4#```'#X``"@,```<+```
M/`P``!PM``!$#```'"X``&P,```</P``>`P``!PL``",#```'"T``)0,```<
M+@``P`P``!P:``#8#```'"(``.@,```<,@``$`T``!PJ```@#0``'#L``#`-
M```"%@``-`T```(4``#4#0``'"@``!0.```</0``.`X``!PL``!,#@``'"T`
M`%0.```<+@``>`X``!PB``"(#@``'#(``*@.```<*@```````"H"````````
M`!L```@````J`@``$````"H"```8````*@(``"`````J`@``*````"H"```P
M````*@(``#@````J`@``0````"H"``!(````*@(``%`````J`@``6````"H"
"````
M`#"@X00@D>4-$=+C$P``&@$#$N,'```:!CN`XAPP@^(#(`+B`@*#X``0H.,0
M(*#C_O__ZPD``.I7#8#B*`"`XN`0@^+^___K`$!0X@,```H1#H3B`!"@XQ`@
MH./^___K`0"@XQ"`O>AP0"WI`4"@X0%@H.$`4*#A`0!PX@``H#.A#Y#A%0``
M&@,`4>,3``"*7PV%X@0`@.(!`H#@`!"@XQ`@H./^___K!0"@X5X=A>(X$('B
M!""@X0`PH./^___K!DR$X@11A>`$4(7B`#"@XP`PA>4#0%#@`4"@$P```.H`
M0*#C!`"@X7"`O>AP0"WI`$"@X0%0H.$$8)'E`V'&XP0`5N,`0*##(```R@@P
MD>4%`%/C`2"@`[PW`0,#((0'!@``"@T`4^,`(*`3O#<!$P,@A!<%(*`#O#<!
M`P,@A`=?#X;B``*$X`0`@.(,$(7B"""5Y?[__^L&/(;B`S&$X`@@E>4$((/E
M7SV@XP-@A.<$`*#A7AV$XC@0@>(&(*#A`3"@X_[__^L`0%#B`4"@$P0`H.%P
M@+WH\$<MZ0C03>(`0*#A`5"@X00PD>4``%/C`@``N@$!$^,N```*00$`Z@$!
M$^,K```*5PV`XB@`@.+@$(3B_O__ZP!@4.($```*N#<!XP,PE.<"`%/C[&"6
M!0$```J\-P'C`V"4YP0PU>4``%/C+P$`&@PPE>4!`'/C,`$`&K`AU>'_/P_C
M`P!2X2P!`!HG`0#J"#"5Y2``4^,D`0`:3```Z@0`5N,)```:"#"5Y1``4^,&
M```*(`!3XQP!`!H0,*#C"#"%Y0!PH.,'@*#A1```Z@4`5N,!`%83%`$`"CP`
M`.H@.P'C`S"4YP,`4^,3``"*%#@!XP,PE.<``%/C#P``&@@PE>4%`%/C`2"@
M`[PW`0,#((0'!@``"@T`4^,`(*`3O#<!$P,@A!<%(*`#O#<!`P,@A`>\-P'C
M`V"4YP$``.H4.`'C`V"4YVPPE.4@`!/C!@``"@PPE>4!`'/C\P``&K`AU>'_
M/P_C`P!2X>\``!H"`%;C`P``&@@PE>4@`%/CZ@``&@@``.H$`%;C!@``&@@P
ME>40`%/C(`!3$^,``!H@`%/C$#"@`P@PA04$<)7EUWW@YVPPE.4@`!/C!P``
M"@$`$^,!<*`3!X"@$0,```H#``#J`'"@XP>`H.$```#J`8"@X[@W`>,#,)3G
M`@!3XR0```H%`%;C`0!6$R$``!H(()7E("""XJ`^`>,#((3G!&"5Y0)AQN.D
M/@'C`V"$YP@@E>6H/@'C`R"$YR!PA>)ZC83B+`"(X@<0H.$(()7E_O__ZU\/
MAN(``H3@!`"`X@<0H.$(()7E_O__ZP8\AN(#,83@"""5Y00@@^5?/:#C`V"$
MYP0`H.$@$(CB_O__ZP%`H..J``#J!#"5Y0("$^,;```*`0!8XPP``!K8`<7A
M`"#@X_\_#^,`(`+@`3`#X`@0C>+X(&'A8PV$XB@`@.(-$*#A"""@X_[__^L.
M``#JV`'%X0`@X./_/P_C`"`"X`$P`^`($(WB^"!AX6,-A.(@`(#B#1"@X0@@
MH./^___K4```Z@$`6.-.```:`0!7XP0@U048.`$#`R"$!P0PE>4#`!/C@0``
M"@9KA.(<8(;B`S`#X@,"AN``$*#C$""@X_[__^MA?83B''"'X@0`U>4#``#B
M``*'X``0H.,0(*#C_O__ZV*-A.(<@(CB!`#5Y0,``.(``HC@`!"@XQ`@H./^
M___K!#"5Y0$"$^,+```*`S`#X@,"A^`P$(7B"""@X_[__^L$`-7E`P``X@`"
MB.`X$(7B"""@X_[__^L*``#J`S`#X@,"A^`X$(7B"""@X_[__^L$`-7E`P``
MX@`"B.`P$(7B"""@X_[__^L$`-7E`P``X@`"AN`@$(7B"""5Y?[__^L$,)7E
M`S`#X@0PA>4!,*#C$"L!XP(PQ.<`$*#C$BL!XP(0Q.<$`*#A7AV$XC@0@>($
M()7E_O__ZP!`4.(!0*`3.@``ZE<-A.(H`(#BX!"$XO[__^L`@%#B`4"@`S,`
M``H1KHCB"@"@X0`0H.,0(*#C_O__ZR"0A>(*`*#A"1"@X1`@H./^___K`@!6
MXQ8``!H`(*#C$3L!XP,@Q.<$,)7E`0(3XP@```KP`(CB$!")X@@@H./^___K
M`0R(XA@0B>(((*#C_O__ZP<``.KP`(CB&!")X@@@H./^___K`0R(XA`0B>((
M(*#C_O__ZP``5^,%```*!`"@X0@0H.$`(*#C_O__ZP!`H.$$``#J!`"@X0@0
MH.$!(*#C_O__ZP!`H.$`0%3B`4"@$P```.H`0*#C!`"@X0C0C>+PA[WH`@!6
MX]7^_QK0_O_J$$`MZ5Y-@.(X0(3B(#L!XP,0@.<#`%'C`B"@@[@W`8,#(("'
M!!"@X?[__^L!`%#C``"@$P$`H`,0@+WH<$`MZ2C03>(`0%#B'@``"ITU`^,#
M,-3G``!3XQH```IL,)3E(@T3XQD``!H4-=3E`0!3XQ8```K^___K#3"@X7]M
MP^,_8,;C!#"6Y0$P@^($,(;E!%"-X@4`H.$`$*#C)""@X_[__^L$`*#A!1"@
MX?[__^L`0*#A!#"6Y0$P0^($,(;E_O__ZP(``.H`0*#C````Z@%`H.,$`*#A
M*-"-XG"`O>@00"WI`$"@X?[__^L-(*#A?SW"XS\PP^,$()/E`2""X@0@@^5L
M,)3E`0`3XP4```H$`*#A_O__ZP0`H.'^___K!`"@X?[__^L-(*#A?SW"XS\P
MP^,$()/E`2!"X@0@@^7^___K`0"@XQ"`O>AP0"WI`$"@X0%0H.$X,9#E`0!3
MX3X```K^___K#2"@X7\]PN,_,,/C!""3Y0$@@N($((/E;#"4Y0$`$^,"```:
M."&4Y0``4N,$```:!`"@X?[__^ML,)3E`0`3XP$``!I``!/C!```"@0`H.'^
M___K;#"4Y0$`$^,$```:.#&4Y0$`4^,!```*``!3XP$``!H$`*#A_O__ZS@Q
ME.4$`%/C`P``&@`PX./8,(3E!`"@X?[__^LX483E;#"4Y7@PP^-L,(3E`0!5
MXP@P@P-L,(0%"```"B`P@S-L,(0U!0``.@0`5>,#```:$#"#XVPPA.4$`*#A
M_O__ZPT@H.%_/<+C/S##XP0@D^4!($+B!""#Y?[__^L!`*#C<("]Z'!`+>D`
M0*#AA%"0Y0$PX./8,(#E;#"0Y8`P@^-L,(#E>%"`Y0$PH.-P,,#EA`"`XO[_
M_^L!`%#C#0``&FPPE.6`,,/C;#"$Y10UU.4``%/C`@``"G$PU.4``%/C/```
M"@0`H.&4$(3B_O__ZP!`H.$X``#J;`"$XO[__^L!`%#C"P``&@`PH.-P,,3E
M`#``XP`P0.,`$)/E10Z$X@@`@.*B'X'B`A"!XO[__^L!0*#C*```ZFPPE.4@
M`!/C%P``"D`PH.-L,(3EJ6V$XCU0AN(%`*#A`!"@XR0@H./^___K!0"@X900
MA.(D(*#C_O__ZP0`H.'^___K-0"&XO[__^L$`*#A_O__ZP$`4.,`0*`3`#"@
M`W`PQ`4!0*`##0``ZH`PP^-L,(3E%#74Y0``4^,"```*<3#4Y0``4^,$```*
M!`"@X900A.+^___K`$"@X0```.H!0*#C!`"@X7"`O>CP02WI`%"@X0%PH.&=
M-0/C`S#0YP``4^,`0*`#;P``"FPPD.6``!/C`4"@$VL``!H""Q/C:P``&A``
M`.IL,)7E`@L3XP4```H&`*#A_O__ZP%`1.(!`'3C]___&@$``.H``%3C!0``
MRHP!G^6,$9_E_O__ZVQ`E>740^#G4```ZO[__^L-(*#A?SW"XS\PP^,$()/E
M`2""X@0@@^5L,)7E00`3XS,```J4()7E`#"7Y0,`4N$A```:F`"%X@00A^+^
M___K`0!0XQP``!IL,)7E"``3XQ0``!H%`*#AP!"%XO[__^L``%#C`4"@$S0`
M`!H%`*#A_O__ZVPPE>4!`!/C`0``"@4`H.'^___K!0"@X?[__^ML,)7E0``3
MXT`PPQ,@,(,3;#"%%1(``.H%`*#A`1"@XP$@H.'^___K#0``Z@4`H.'^___K
M;#"5Y0$`$^,!```*!0"@X?[__^L%`*#A_O__ZVPPE>5``!/C0###$R`P@Q-L
M,(45&#8"XP,PU><!`%/C#0``"@<`H.'^___K``!0XPD```J4`(7B!Q"@X20@
MH./^___K`#"@XXPTA>4%`*#A_O__ZP!`H.$```#J`$"@XPT@H.%_/<+C/S##
MXP0@D^4!($+B!""#Y?[__^L$`*#A\(&]Z&0`H./^___K,$"@XV1@H../___J
M``````````!P0"WI`$"@X0%0H.$`,-'E``!3XP\``!H!(-'E``!2XPP``!H"
M,-'E``!3XQH``!H#,-'E``!3XQ<``!H$,-'E``!3XQ0``!H%,-'E``!3XQ$`
M`!I'``#J_P!3XPX``!H!,-7E_P!3XPL``!H",-7E_P!3XP@``!H#,-7E_P!3
MXP4``!H$,-7E_P!3XP(``!H%,-7E_P!3XS8```K^___K#2"@X7\]PN,_,,/C
M!""3Y0$@@N($((/E;#"4Y2(-$^/30^`7(P``&D$`$^,8```*X`"$X@40H.$&
M(*#C_O__ZP$`4.,$```:;#"4Y0@`$^,!0*`#%P``"@T``.H$`*#A_O__ZVPP
ME.4!`!/C`0``"@0`H.'^___K!`"@X?[__^ML,)3E0``3XT`PPQ,@,(,3;#"$
M%;@`A.(%$*#A!B"@X_[__^L!,*#CC#2$Y00`H.'^___K`$"@X0T@H.%_/<+C
M/S##XP0@D^4!($+B!""#Y?[__^L```#J`$"@XP0`H.%P@+WH`````+"PH(!\
M````L+"H@.@```"PL*J`;`$``+"PJH`8`@``L*X!@&0'``"PL*B`H`<``+"J
M"8!$"```L+"H@+`(``"PL*J`S`D``+"PJH`L"P``L+"L@#`-``"PL*J`<G1W
M7W-E=%\X,#)?,3%?<W-I9``E<SH@4V5T(%-3240@:7,@;F]T(&%L;&]W960@
M=6YD97(@<W5R=F5Y:6YG"@``````1T-#.B`H1TY5*2`T+C0N,`!!*@```&%E
M86)I``$@````!3<M00`&"@=!"`$2!!0!%0$7`Q@!&0$:`AX!`"YS>6UT86(`
M+G-T<G1A8@`N<VAS=')T86(`+G)E;"YT97AT`"YD871A`"YB<W,`+D%232YE
M>'1A8@`N<F5L+D%232YE>&ED>``N<F]D871A`"YR;V1A=&$N<W1R,2XT`"YC
M;VUM96YT`"YN;W1E+D=.52US=&%C:P`N05)-+F%T=')I8G5T97,`````````
M```````````````````````````````````````````````?`````0````8`
M````````-````+0.``````````````0`````````&P````D`````````````
M``@:``"X`@``#@````$````$````"````"4````!`````P````````#H#@``
M`````````````````0`````````K````"`````,`````````Z`X`````````
M``````````$`````````,`````$````"`````````.@.````````````````
M```!`````````#\````!``!P@@````````#H#@``8`````$`````````!```
M```````[````"0``````````````P!P``&@````.````!@````0````(````
M2@````$````"`````````$@/```4```````````````$`````````%(````!
M````,@````````!<#P``,```````````````!`````$```!A`````0``````
M````````C`\``!(```````````````$`````````:@````$`````````````
M`)X/```````````````````!`````````'H````#``!P``````````">#P``
M*P```````````````0`````````1`````P``````````````R0\``(H`````
M``````````$``````````0````(``````````````-02```0!```#P```!H`
M```$````$`````D````#``````````````#D%@``(P,``````````````0``
M`````````````````````````````0``````````````!`#Q_P``````````
M``````,``0`````````````````#``,``````````````````P`$`!$`````
M`````````````0`````````````````#``4``````````````````P`&`!$`
M``!\`````````````0`1````Z`````````````$`$0```&P!```````````!
M`!$````8`@```````````0`1````9`<```````````$`$0```*`'````````
M```!`!$```!$"````````````0`1````L`@```````````$`$0```,P)````
M```````!`!$````L"P```````````0`4````*`T```````````$`$0```#`-
M```````````!``````````````````,`"``7`````````!0````!``@`````
M`````````````P`)``````````````````,`"P`````````````````#``H`
M`````````````````P`,`"8`````````?````!(``0`X```````````````0
M````3P```'P```!L````$@`!`&D``````````````!````!U````````````
M```0````A0```.@```"$````$@`!`)\``````````````!````"K````;`$`
M`*P````2``$`P@``````````````$````,X````8`@``3`4``!(``0#E````
M```````````0````]P```&0'```\````$@`!`!H!`````````````!`````G
M`0``H`<``*0````2``$`1@$`````````````$````%<!`````````````!``
M``!J`0`````````````0````>@$``$0(``!L````$@`!`)8!````````````
M`!````"G`0`````````````0````OP$`````````````$````-@!``"P"```
M'`$``!(``0#[`0`````````````0````"`(`````````````$````!8"``#,
M"0``8`$``!(``0`B`@`````````````0````,P(`````````````$````%H"
M`````````````!````!B`@`````````````0````;`(`````````````$```
M`)`"`````````````!````"I`@`````````````0````NP(``"P+```$`@``
M$@`!`,\"`````````````!````#6`@`````````````0````W0(`````````
M````$````.D"`````````````!````#Z`@`````````````0````#@,``#`-
M``"$`0``$@`!``!R='=?:6]C=&Q?<V5T+F,`)&$`)&0`7U]F=6YC7U\N,SDP
M,C,`<G1W7W9A;&ED871E7W-S:60`7U]A96%B:5]U;G=I;F1?8W!P7W!R,`!R
M='=?<V5T7S@P,E\Q,5]R96UO=F5?:V5Y`%]R='=?;65M<V5T`')T=U]G971?
M<W1A:6YF;P!R='=?<V5T7S@P,E\Q,5]R96UO=F5?=V5P`')T=U]S971?:V5Y
M`')T=U]S971?.#`R7S$Q7V%D9%]W97``7W)T=U]M96UC<'D`<G1W7W-E=%\X
M,#)?,3%?861D7VME>0!R='=?<V5T<W1A:V5Y7V-M9`!R='=?<V5T7S@P,E\Q
M,5]A=71H96YT:6-A=&EO;E]M;V1E`')T=U]S971?875T:`!R='=?<V5T7S@P
M,E\Q,5]B<W-I9%]L:7-T7W-C86X`;&]C86Q?8FA?9&ES86)L90!R='=?<VET
M97-U<G9E>5]C;60`;&]C86Q?8FA?96YA8FQE`')T=U]S971?.#`R7S$Q7V1I
M<V%S<V]C:6%T90!R='=?9&ES87-S;V-?8VUD`')T=U]I;F1I8V%T95]D:7-C
M;VYN96-T`')T=U]F<F5E7V%S<V]C7W)E<V]U<F-E<P!R='=?<V5T7S@P,E\Q
M,5]I;F9R87-T<G5C='5R95]M;V1E`'-T;W!?87!?;6]D90!S=&%R=%]A<%]M
M;V1E`')T=U]D;U]J;VEN`%]R='=?<75E=65?96UP='D`<G1W7W-E;&5C=%]A
M;F1?:F]I;E]F<F]M7W-C86YN961?<75E=64`:FEF9FEE<P!M;V1?=&EM97(`
M<G1W7W5P9&%T95]R96=I<W1R>7!R:79?9&5V7VYE='=O<FL`<G1W7V=E;F5R
M871E7W)A;F1O;5]I8G-S`')T=U]C<F5A=&5B<W-?8VUD`')T=U]S971?.#`R
M7S$Q7W-S:60`;7-L965P`'!R:6YT:P!?<G1W7VUE;6-M<`!R='=?:7-?<V%M
M95]I8G-S`')T=U]L<'-?8W1R;%]W:U]C;60`<G1W7W-E=%\X,#)?,3%?8G-S
M:60``+`````<'0``Q````!P>``#<````'!T``"0!```<'0``/`$``!P@``#4
M`0``'"(```0"```<(```5`(``!P>``!8!```'"(``'`$```<(@``E`0``!PA
M``#@!```'"(``!0%```<(@``6`4``!P=``!X!0``'!T``)@%```<'0``N`4`
M`!PB``#0!0``'"(``.@%```<(@````8``!PB```8!@``'"(``%`&```<(```
M;`8``!P>``",!@``'!T``*`&```<(@``T`8``!PB``#@!@``'"(``/0&```<
M(@``!`<``!PB```<!P``'"0``#0'```<)```C`<``!PF``#8!P``'"@```0(
M```<'0``$`@``!PI```D"```'"H``$P(```<*```>`@``!PL``"`"```'"T`
M`(@(```<+@``I`@``!PJ``#("```'"@````)```<+```'`D``!PN``!$"0``
M'"T``&`)```<,```I`D``!PQ``#`"0``'"H``/P)```<,P``-`H``!PI``!$
M"@``'#0``%@*```K-0``7`H``"PU``!T"@``'#8``*@*```<'0``N`H``!PB
M``#`"@``'#<``,@*```<.```T`H``!PY```4"P``'"D``'@+```<.P``G`L`
M`!P\``"L"P``'"@``.P+```</0``#`P``!P^```@#```'"P``#0,```<+0``
M/`P``!PN``!D#```'#\``'`,```<+```A`P``!PM``",#```'"X``+@,```<
M&@``T`P``!PB``#@#```'#(```@-```<*@``&`T``!P[```H#0```A8``"P-
M```"%```S`T``!PH```,#@``'#T``#`.```<+```1`X``!PM``!,#@``'"X`
M`'`.```<(@``@`X``!PR``"@#@``'"H````````J`@`````````;```(````
M*@(``!`````J`@``&````"H"```@````*@(``"@````J`@``,````"H"```X
G````*@(``$`````J`@``2````"H"``!0````*@(``%@````J`@``
`
end

View File

@@ -5605,6 +5605,10 @@ void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
/*
* Send a deauth message before auth. (meitu's disconnect issue)
*/
issue_deauth( padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
{
@@ -5909,20 +5913,24 @@ void issue_assocreq(_adapter *padapter)
struct ieee80211_hdr *pwlanhdr;
unsigned short *fctrl;
unsigned short val16;
unsigned int i, ie_len;
unsigned char rf_type, bssrate[NumRates];
unsigned int i, j, ie_len, index=0;
unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
PNDIS_802_11_VARIABLE_IEs pIE;
struct registry_priv *pregpriv = &padapter->registrypriv;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
int bssrate_len = 0;
int bssrate_len = 0, sta_bssrate_len = 0;
#ifdef CONFIG_P2P
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
u8 p2pie[ 255 ] = { 0x00 };
u16 p2pielen = 0;
#endif //CONFIG_P2P
#ifdef CONFIG_DFS
u16 cap;
#endif //CONFIG_DFS
if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
{
return;
@@ -5952,8 +5960,13 @@ void issue_assocreq(_adapter *padapter)
pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
//caps
#ifdef CONFIG_DFS
_rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
cap |= BIT(8);
_rtw_memcpy(pframe, &cap, 2);
#else
_rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
#endif //CONFIG_DFS
pframe += 2;
pattrib->pktlen += 2;
@@ -5969,15 +5982,56 @@ void issue_assocreq(_adapter *padapter)
pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
//supported rate & extended supported rate
#if 1 // Check if the AP's supported rates are also supported by STA.
get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
//DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
//for (i = 0; i < sta_bssrate_len; i++) {
// DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
//}
for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
if (pmlmeinfo->network.SupportedRates[i] == 0) break;
DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
}
for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
if (pmlmeinfo->network.SupportedRates[i] == 0) break;
// Check if the AP's supported rates are also supported by STA.
for (j=0; j < sta_bssrate_len; j++) {
// Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
== (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
//DBG_871X("match i = %d, j=%d\n", i, j);
break;
} else {
//DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
}
}
if (j == sta_bssrate_len) {
// the rate is not supported by STA
DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
} else {
// the rate is supported by STA
bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
}
}
bssrate_len = index;
DBG_871X("bssrate_len = %d\n", bssrate_len);
#else // Check if the AP's supported rates are also supported by STA.
#if 0
get_rate_set(padapter, bssrate, &bssrate_len);
#else
for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
break;
bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
}
#endif
#endif // Check if the AP's supported rates are also supported by STA.
if (bssrate_len > 8)
{
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));

Some files were not shown because too many files have changed in this diff Show More