mirror of
https://github.com/hardkernel/linux.git
synced 2026-04-16 18:40:44 +09:00
Merge remote-tracking branch 'last/develop-3.0' into develop-3.0
This commit is contained in:
File diff suppressed because it is too large
Load Diff
2653
arch/arm/configs/rk29_k97_defconfig
Normal file
2653
arch/arm/configs/rk29_k97_defconfig
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
#
|
||||
|
||||
2162
arch/arm/configs/rk29_td8801_v2_defconfig
Normal file
2162
arch/arm/configs/rk29_td8801_v2_defconfig
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
3075
arch/arm/mach-rk29/board-rk29-k97.c
Executable file
3075
arch/arm/mach-rk29/board-rk29-k97.c
Executable file
File diff suppressed because it is too large
Load Diff
@@ -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,
|
||||
|
||||
105
arch/arm/mach-rk29/board-rk29-td8801_v2-key.c
Normal file
105
arch/arm/mach-rk29/board-rk29-td8801_v2-key.c
Normal 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
|
||||
};
|
||||
313
arch/arm/mach-rk29/board-rk29-td8801_v2-rfkill.c
Normal file
313
arch/arm/mach-rk29/board-rk29-td8801_v2-rfkill.c
Normal 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");
|
||||
3659
arch/arm/mach-rk29/board-rk29-td8801_v2.c
Executable file
3659
arch/arm/mach-rk29/board-rk29-td8801_v2.c
Executable file
File diff suppressed because it is too large
Load Diff
108
arch/arm/mach-rk29/board-rk29k97-key.c
Executable file
108
arch/arm/mach-rk29/board-rk29k97-key.c
Executable 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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
920
drivers/input/gsensor/bma023.c
Normal file
920
drivers/input/gsensor/bma023.c
Normal 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);
|
||||
@@ -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
|
||||
|
||||
@@ -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
833
drivers/input/misc/al3006.c
Normal 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 *)®
|
||||
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);
|
||||
33
drivers/input/misc/al3006.h
Normal file
33
drivers/input/misc/al3006.h
Normal 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
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
920
drivers/input/touchscreen/pixcir_i2c_ts.c
Normal file
920
drivers/input/touchscreen/pixcir_i2c_ts.c
Normal 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");
|
||||
74
drivers/input/touchscreen/pixcir_i2c_ts.h
Normal file
74
drivers/input/touchscreen/pixcir_i2c_ts.h
Normal 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
|
||||
1651
drivers/input/touchscreen/rk29_i2c_goodix.c
Executable file
1651
drivers/input/touchscreen/rk29_i2c_goodix.c
Executable file
File diff suppressed because it is too large
Load Diff
232
drivers/input/touchscreen/rk29_i2c_goodix.h
Executable file
232
drivers/input/touchscreen/rk29_i2c_goodix.h
Executable 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 */
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
32
drivers/mfd/wm831x-core.c
Normal file → Executable 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
59
drivers/mfd/wm831x-i2c.c
Normal file → Executable 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 *)®
|
||||
|
||||
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);
|
||||
|
||||
@@ -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
70
drivers/mfd/wm831x-spi.c
Normal file → Executable 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);
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
728
drivers/misc/sc8800.c
Executable 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
179
drivers/misc/tdsc8800.c
Executable 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);
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>⡣
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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, ®s->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, ®s->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++;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
1726
drivers/net/wireless/bcm4319/bcmspibrcm.c
Normal file
1726
drivers/net/wireless/bcm4319/bcmspibrcm.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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_ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
#define STATIC static
|
||||
|
||||
|
||||
#define SI_BUS 0
|
||||
#define PCI_BUS 1
|
||||
#define PCMCIA_BUS 2
|
||||
|
||||
@@ -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)
|
||||
|
||||
134
drivers/net/wireless/bcm4319/include/bcmspibrcm.h
Normal file
134
drivers/net/wireless/bcm4319/include/bcmspibrcm.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
153
drivers/net/wireless/bcm4319/include/spid.h
Normal file
153
drivers/net/wireless/bcm4319/include/spid.h
Normal 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 */
|
||||
9
drivers/net/wireless/bcm4319/include/wifi_version.h
Normal file
9
drivers/net/wireless/bcm4319/include/wifi_version.h
Normal 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 */
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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 {} \;
|
||||
|
||||
@@ -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"
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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"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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user