aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/battery/battery-factory.c24
-rw-r--r--drivers/battery/max17047_fuelgauge.c149
-rw-r--r--drivers/battery/max77693_charger.c204
-rw-r--r--drivers/battery/samsung_battery.c82
-rw-r--r--drivers/input/keyboard/cypress/cypress-touchkey.c33
-rw-r--r--drivers/input/touchscreen/mms_ts.c13
-rw-r--r--drivers/leds/leds-aat1290a.c2
-rw-r--r--drivers/leds/leds-an30259a.c22
-rw-r--r--drivers/media/video/s5c73m3.c307
-rw-r--r--drivers/media/video/s5c73m3.h8
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h3
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x.h1
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c11
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c11
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c12
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c57
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_notification.c7
-rw-r--r--drivers/media/video/samsung/mfc5x/mfc_dec.c6
-rw-r--r--drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c5
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c4
-rw-r--r--drivers/mmc/card/block.c27
-rw-r--r--drivers/mmc/core/core.c5
-rw-r--r--drivers/mmc/core/mmc.c163
-rw-r--r--drivers/mmc/core/sd.c6
-rw-r--r--drivers/mmc/core/sdio.c8
-rw-r--r--drivers/mmc/host/mshci-s3c.c7
-rw-r--r--drivers/mmc/host/mshci.c7
-rw-r--r--drivers/net/wireless/bcmdhd/Makefile4
-rw-r--r--drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c18
-rw-r--r--drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c9
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h11
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c18
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c53
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c148
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c99
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c72
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h11
-rw-r--r--drivers/net/wireless/bcmdhd/src/include/epivers.h8
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c49
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c215
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h16
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c152
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.h8
-rw-r--r--drivers/rtc/rtc-max77686.c32
-rw-r--r--drivers/sensor/lsm330dlc_gyro.c4
-rw-r--r--drivers/usb/gadget/f_mtp_samsung.c80
-rw-r--r--drivers/video/samsung/Kconfig32
-rw-r--r--drivers/video/samsung/lcdfreq.c31
-rw-r--r--drivers/video/samsung/mdnie.c90
-rw-r--r--drivers/video/samsung/mdnie.h13
-rw-r--r--drivers/video/samsung/s3cfb.h18
-rw-r--r--drivers/video/samsung/s3cfb_fimd6x.c87
-rw-r--r--drivers/video/samsung/s3cfb_ielcd.c34
-rw-r--r--drivers/video/samsung/s3cfb_ielcd.h4
-rw-r--r--drivers/video/samsung/s3cfb_main.c98
-rw-r--r--drivers/video/samsung/s3cfb_mdnie.c16
-rw-r--r--drivers/video/samsung/s3cfb_mdnie.h4
-rw-r--r--drivers/video/samsung/s3cfb_ops.c37
-rw-r--r--drivers/video/samsung/s3cfb_s6e39a0.c52
-rw-r--r--drivers/video/samsung/s3cfb_s6e8aa0.c107
-rw-r--r--drivers/video/samsung/s3cfb_s6e8ab0.c50
-rw-r--r--drivers/video/samsung/s5p-dsim.c753
-rw-r--r--drivers/video/samsung/s5p-dsim.h44
-rw-r--r--drivers/video/samsung/s6d6aa1.c70
-rw-r--r--drivers/video/samsung/s6dr171.c49
-rw-r--r--drivers/video/samsung/s6e8aa0_param.h4
-rw-r--r--drivers/video/samsung/smart_dimming.c2
67 files changed, 2253 insertions, 1533 deletions
diff --git a/drivers/battery/battery-factory.c b/drivers/battery/battery-factory.c
index d617a01..e244c8e 100644
--- a/drivers/battery/battery-factory.c
+++ b/drivers/battery/battery-factory.c
@@ -50,6 +50,8 @@ static struct device_attribute battery_attrs[] = {
BATTERY_ATTR(siop_activated),
BATTERY_ATTR(wc_status),
BATTERY_ATTR(wpc_pin_state),
+ BATTERY_ATTR(factory_mode),
+ BATTERY_ATTR(update),
/* not use */
BATTERY_ATTR(batt_vol_adc),
@@ -82,6 +84,8 @@ enum {
SIOP_ACTIVATED,
WC_STATUS,
WPC_PIN_STATE,
+ FACTORY_MODE,
+ UPDATE,
/* not use */
BATT_VOL_ADC,
@@ -207,6 +211,10 @@ static ssize_t battery_show_property(struct device *dev,
#endif
i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
break;
+ case FACTORY_MODE:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
+ info->factory_mode);
+ break;
case BATT_VOL_ADC:
case BATT_VOL_ADC_CAL:
case BATT_VOL_ADC_AVER:
@@ -291,6 +299,22 @@ static ssize_t battery_store_property(struct device *dev,
ret = count;
}
break;
+ case FACTORY_MODE:
+ if (sscanf(buf, "%d\n", &x) == 1) {
+ if (x)
+ info->factory_mode = true;
+ else
+ info->factory_mode = false;
+
+ pr_info("%s: factory mode %s\n", __func__,
+ (info->factory_mode ? "set" : "clear"));
+ ret = count;
+ }
+ break;
+ case UPDATE:
+ pr_info("%s: battery update\n", __func__);
+ ret = count;
+ break;
default:
ret = -EINVAL;
}
diff --git a/drivers/battery/max17047_fuelgauge.c b/drivers/battery/max17047_fuelgauge.c
index ae462a6..fc01547 100644
--- a/drivers/battery/max17047_fuelgauge.c
+++ b/drivers/battery/max17047_fuelgauge.c
@@ -37,11 +37,6 @@
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#endif
-/* adjust full soc */
-#define FULL_SOC_DEFAULT 9850
-#define FULL_SOC_LOW 9700
-#define FULL_SOC_HIGH 10000
-#define KEEP_SOC_DEFAULT 50 /* 0.5% */
#endif
/* TRIM ERROR DETECTION */
@@ -69,9 +64,11 @@
#undef DEBUG_FUELGAUGE_POLLING
#define MAX17047_POLLING_INTERVAL 10000
-#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
-static void max17047_adjust_fullsoc(struct i2c_client *client);
-#endif
+/* adjust full soc */
+#define FULL_SOC_DEFAULT 9850
+#define FULL_SOC_LOW 9700
+#define FULL_SOC_HIGH 10000
+#define KEEP_SOC_DEFAULT 50 /* 0.5% */
struct max17047_fuelgauge_data {
struct i2c_client *client;
@@ -100,14 +97,12 @@ struct max17047_fuelgauge_data {
unsigned int rawsoc;
unsigned int temperature;
-#if defined(CONFIG_TARGET_LOCALE_KOR)
+ /* adjust full soc */
int full_soc;
+
#ifdef CONFIG_DEBUG_FS
struct dentry *fg_debugfs_dir;
#endif
-#elif defined(CONFIG_MACH_M0_CTC)
- int full_soc;
-#endif
#ifdef CONFIG_HIBERNATION
u8 *reg_dump;
@@ -270,10 +265,6 @@ static int max17047_get_soc(struct i2c_client *client)
rawsoc = max17047_get_rawsoc(fg_data->client);
-#if defined(CONFIG_BATTERY_SAMSUNG_S2PLUS)
- soc = fg_data->soc
- = (rawsoc < 300) ? 0 : ((rawsoc - 300) * 100 / 9200) + 1;
-#else
#if defined(CONFIG_MACH_C1_KOR_SKT) || \
defined(CONFIG_MACH_C1_KOR_KT) || \
defined(CONFIG_MACH_C1_KOR_LGT)
@@ -291,19 +282,30 @@ static int max17047_get_soc(struct i2c_client *client)
soc = fg_data->soc =
((rawsoc < 29) ? 0 : (min(((rawsoc - 29) * 100 /
(fg_data->full_soc - 29)), 100)));
+#elif defined(CONFIG_MACH_T0_KOR_SKT) || \
+ defined(CONFIG_MACH_T0_KOR_KT) || \
+ defined(CONFIG_MACH_T0_KOR_LGT)
+ if (fg_data->full_soc <= 0)
+ fg_data->full_soc = FULL_SOC_DEFAULT;
+
+ soc = fg_data->soc =
+ ((rawsoc < 29) ? 0 : (min(((rawsoc - 29) * 100 /
+ (fg_data->full_soc - 29)), 100)));
#elif defined(CONFIG_MACH_M0_CTC)
if (fg_data->full_soc <= 0)
fg_data->full_soc = FULL_SOC_DEFAULT;
soc = fg_data->soc =
((rawsoc < 29) ? 0 : (min(((rawsoc - 29) * 100 /
- (fg_data->full_soc - 29)), 100)));
+ (fg_data->full_soc - 29)), 100)));
#else
- /* prevent minus value and add 0.5% up raw soc */
+ /* M0 */
+ if (fg_data->full_soc <= 0)
+ fg_data->full_soc = FULL_SOC_DEFAULT;
+
soc = fg_data->soc =
((rawsoc < 29) ? 0 : (min(((rawsoc - 29) * 100 /
- (10000 - 79)), 100)));
-#endif
+ (fg_data->full_soc - 29)), 100)));
#endif
pr_debug("%s: SOC(%d, %d)\n", __func__, soc, rawsoc);
@@ -341,6 +343,38 @@ static void max17047_reset_soc(struct i2c_client *client)
return;
}
+static void max17047_adjust_fullsoc(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data =
+ i2c_get_clientdata(client);
+ int prev_full_soc = fg_data->full_soc;
+ int temp_soc = max17047_get_rawsoc(fg_data->client);
+ int keep_soc = 0;
+
+ if (temp_soc < 0) {
+ pr_err("%s : fg data error!(%d)\n", __func__, temp_soc);
+ fg_data->full_soc = FULL_SOC_DEFAULT;
+ return;
+ }
+
+ if (temp_soc < FULL_SOC_LOW)
+ fg_data->full_soc = FULL_SOC_LOW;
+ else if (temp_soc > FULL_SOC_HIGH) {
+ keep_soc = FULL_SOC_HIGH / 100;
+ fg_data->full_soc = (FULL_SOC_HIGH - keep_soc);
+ } else {
+ keep_soc = temp_soc / 100;
+ if (temp_soc > (FULL_SOC_LOW + keep_soc))
+ fg_data->full_soc = temp_soc - keep_soc;
+ else
+ fg_data->full_soc = FULL_SOC_LOW;
+ }
+
+ if (prev_full_soc != fg_data->full_soc)
+ pr_info("%s : full_soc = %d, keep_soc = %d\n", __func__,
+ fg_data->full_soc, keep_soc);
+}
+
/* SOC% alert, disabled(0xFF00) */
static void max17047_set_salrt(struct max17047_fuelgauge_data *fg_data,
u8 min, u8 max)
@@ -425,24 +459,6 @@ static void max17047_reg_init(struct max17047_fuelgauge_data *fg_data)
u8 i2c_data[2];
pr_debug("%s\n", __func__);
-
-#if defined(CONFIG_BATTERY_SAMSUNG_S2PLUS)
- i2c_data[1] = 0x00;
- i2c_data[0] = 0x00;
- max17047_i2c_write(client, MAX17047_REG_CGAIN, i2c_data);
-
- i2c_data[1] = 0x00;
- i2c_data[0] = 0x03;
- max17047_i2c_write(client, MAX17047_REG_MISCCFG, i2c_data);
-
- i2c_data[1] = 0x00;
- i2c_data[0] = 0x07;
- max17047_i2c_write(client, MAX17047_REG_LEARNCFG, i2c_data);
-
- i2c_data[1] = 0x00;
- i2c_data[0] = 0x50;
- max17047_i2c_write(client, MAX17047_REG_RCOMP, i2c_data);
-#else /* Use MG1 */
i2c_data[1] = 0x00;
i2c_data[0] = 0x00;
max17047_i2c_write(client, MAX17047_REG_CGAIN, i2c_data);
@@ -454,7 +470,6 @@ static void max17047_reg_init(struct max17047_fuelgauge_data *fg_data)
i2c_data[1] = 0x07;
i2c_data[0] = 0x00;
max17047_i2c_write(client, MAX17047_REG_LEARNCFG, i2c_data);
-#endif
}
static void max17047_update_work(struct work_struct *work)
@@ -607,18 +622,16 @@ static int max17047_get_property(struct power_supply *psy,
switch (val->intval) {
case SOC_TYPE_ADJUSTED:
val->intval = max17047_get_soc(fg_data->client);
- break;
+ break;
case SOC_TYPE_RAW:
val->intval = max17047_get_rawsoc(fg_data->client);
- break;
-#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
+ break;
case SOC_TYPE_FULL:
val->intval = fg_data->full_soc;
- break;
-#endif
+ break;
default:
val->intval = max17047_get_soc(fg_data->client);
- break;
+ break;
}
break;
case POWER_SUPPLY_PROP_TEMP:
@@ -643,7 +656,6 @@ static int max17047_set_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_CAPACITY:
max17047_reset_soc(fg_data->client);
break;
-#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
case POWER_SUPPLY_PROP_STATUS:
if (val->intval != POWER_SUPPLY_STATUS_FULL)
return -EINVAL;
@@ -651,7 +663,6 @@ static int max17047_set_property(struct power_supply *psy,
/* adjust full soc */
max17047_adjust_fullsoc(fg_data->client);
break;
-#endif
default:
return -EINVAL;
}
@@ -663,7 +674,6 @@ static irqreturn_t max17047_fuelgauge_isr(int irq, void *data)
{
struct max17047_fuelgauge_data *fg_data = data;
struct i2c_client *client = fg_data->client;
- struct power_supply *battery_psy = power_supply_get_by_name("battery");
union power_supply_propval value;
u8 i2c_data[2];
pr_info("%s: irq(%d)\n", __func__, irq);
@@ -680,40 +690,6 @@ static irqreturn_t max17047_fuelgauge_isr(int irq, void *data)
return IRQ_HANDLED;
}
-#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
-static void max17047_adjust_fullsoc(struct i2c_client *client)
-{
- struct max17047_fuelgauge_data *fg_data =
- i2c_get_clientdata(client);
- int prev_full_soc = fg_data->full_soc;
- int temp_soc = max17047_get_rawsoc(fg_data->client);
- int keep_soc = 0;
-
- if (temp_soc < 0) {
- pr_err("%s : fg data error!(%d)\n", __func__, temp_soc);
- fg_data->full_soc = FULL_SOC_DEFAULT;
- return;
- }
-
- if (temp_soc < FULL_SOC_LOW)
- fg_data->full_soc = FULL_SOC_LOW;
- else if (temp_soc > FULL_SOC_HIGH) {
- keep_soc = FULL_SOC_HIGH / 100;
- fg_data->full_soc = (FULL_SOC_HIGH - keep_soc);
- } else {
- keep_soc = temp_soc / 100;
- if (temp_soc > (FULL_SOC_LOW + keep_soc))
- fg_data->full_soc = temp_soc - keep_soc;
- else
- fg_data->full_soc = FULL_SOC_LOW;
- }
-
- if (prev_full_soc != fg_data->full_soc)
- pr_info("%s : full_soc = %d, keep_soc = %d\n", __func__,
- fg_data->full_soc, keep_soc);
-}
-#endif
-
#if defined(CONFIG_TARGET_LOCALE_KOR)
#ifdef CONFIG_DEBUG_FS
static int max17047_debugfs_open(struct inode *inode, struct file *filp)
@@ -868,10 +844,7 @@ static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client,
struct max17047_fuelgauge_data *fg_data;
int ret;
u8 i2c_data[2];
-#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
- int rawsoc;
- int firstsoc;
-#endif
+ int rawsoc, firstsoc;
pr_info("%s: max17047 Fuel gauge Driver Loading\n", __func__);
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
@@ -891,7 +864,6 @@ static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client,
wake_lock_init(&fg_data->update_wake_lock, WAKE_LOCK_SUSPEND,
"fuel-update");
-#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
/* Initialize full_soc, set this before fisrt SOC reading */
fg_data->full_soc = FULL_SOC_DEFAULT;
/* first full_soc update */
@@ -900,8 +872,7 @@ static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client,
max17047_adjust_fullsoc(client);
firstsoc = max17047_get_soc(client);
pr_info("%s: rsoc=%d, fsoc=%d, soc=%d\n", __func__,
- rawsoc, fg_data->full_soc, firstsoc);
-#endif
+ rawsoc, fg_data->full_soc, firstsoc);
if (fg_data->pdata->psy_name)
fg_data->fuelgauge.name =
diff --git a/drivers/battery/max77693_charger.c b/drivers/battery/max77693_charger.c
index 9ed3122..c17bbac 100644
--- a/drivers/battery/max77693_charger.c
+++ b/drivers/battery/max77693_charger.c
@@ -101,8 +101,10 @@
#define MAX77693_CHG_CC 0x3F
/* MAX77693_CHG_REG_CHG_CNFG_04 */
-#define MAX77693_CHG_MINVSYS_MASK 0x1F
-#define MAX77693_CHG_MINVSYS_SHIFT 5
+#define MAX77693_CHG_MINVSYS_MASK 0xE0
+#define MAX77693_CHG_MINVSYS_SHIFT 5
+#define MAX77693_CHG_PRM_MASK 0x1F
+#define MAX77693_CHG_PRM_SHIFT 0
/* MAX77693_CHG_REG_CHG_CNFG_09 */
#define MAX77693_CHG_CHGIN_LIM 0x7F
@@ -114,6 +116,8 @@
/* MAX77693_MUIC_REG_STATUS2 */
#define MAX77693_VBVOLT 0x40
#define MAX77693_VBVOLT_SHIFT 6
+#define MAX77693_DXOVP 0x20
+#define MAX77693_DXOVP_SHIFT 5
#define MAX77693_CHGDETRUN 0x08
#define MAX77693_CHGDETRUN_SHIFT 3
#define MAX77693_CHGTYPE 0x07
@@ -132,12 +136,18 @@
#define SOFT_CHG_CURR_STEP 100 /* mA */
#define SOFT_CHG_STEP_DUR 20 /* ms */
+/* soft regulation */
+#define SW_REG_CURR_STEP_MA 100
+#define SW_REG_START_DELAY 1000
+#define SW_REG_STEP_DELAY 500
+
struct max77693_charger_data {
struct max77693_dev *max77693;
struct power_supply charger;
struct delayed_work update_work;
+ struct delayed_work softreg_work;
/* mutex */
struct mutex irq_lock;
@@ -145,6 +155,7 @@ struct max77693_charger_data {
/* wakelock */
struct wake_lock update_wake_lock;
+ struct wake_lock softreg_wake_lock;
unsigned int charging_state;
unsigned int charging_type;
@@ -331,11 +342,7 @@ static int max77693_get_charger_state(struct max77693_charger_data *chg_data)
max77693_read_reg(i2c, MAX77693_CHG_REG_CHG_DTLS_01, &reg_data);
reg_data = ((reg_data & MAX77693_CHG_DTLS) >> MAX77693_CHG_DTLS_SHIFT);
-#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
- pr_info("%s: CHG_DTLS(0x%02x)\n", __func__, reg_data);
-#else
pr_debug("%s: CHG_DTLS(0x%02x)\n", __func__, reg_data);
-#endif
switch (reg_data) {
case 0x0:
@@ -583,10 +590,10 @@ static bool max77693_get_wc_state(struct max77693_charger_data *chg_data)
/* check chargable dock */
static int max77693_get_dock_type(struct max77693_charger_data *chg_data)
{
- int state;
+ int state = POWER_SUPPLY_TYPE_BATTERY;
u8 reg_data;
int muic_cb_typ;
- u8 mu_st2, vbvolt;
+ u8 mu_st2, vbvolt = 0;
pr_debug("%s\n", __func__);
muic_cb_typ = max77693_muic_get_charging_type();
@@ -632,7 +639,7 @@ static int max77693_get_cable_type(struct max77693_charger_data *chg_data)
int state;
u8 reg_data, mu_adc, mu_adc1k, otg;
u8 dtls_00, chgin_dtls;
- u8 mu_st2, chgdetrun, vbvolt, chgtyp;
+ u8 mu_st2, chgdetrun, vbvolt, chgtyp, dxovp;
bool wc_state;
bool retry_det, chg_det_erred;
int retry_cnt = 0;
@@ -673,7 +680,7 @@ static int max77693_get_cable_type(struct max77693_charger_data *chg_data)
goto chg_det_finish;
}
- chg_det_erred = true; /* TEMP: set as true for logging */
+ chg_det_erred = false; /* TEMP: set as true for logging */
do {
retry_det = false;
@@ -690,7 +697,7 @@ static int max77693_get_cable_type(struct max77693_charger_data *chg_data)
chgtyp = ((mu_st2 & MAX77693_CHGTYPE) >>
MAX77693_CHGTYPE_SHIFT);
if (chg_det_erred)
- pr_info("%s: CHGIN(0x%x). MU_ST2(0x%x), "
+ pr_err("%s: CHGIN(0x%x). MU_ST2(0x%x), "
"CDR(0x%x), VB(0x%x), CHGTYP(0x%x)\n", __func__,
chgin_dtls, mu_st2,
chgdetrun, vbvolt, chgtyp);
@@ -699,13 +706,14 @@ static int max77693_get_cable_type(struct max77693_charger_data *chg_data)
if (((chgin_dtls != 0x0) && (vbvolt == 0x1)) ||
((chgin_dtls == 0x0) && (vbvolt == 0x0)) ||
(chg_data->reg_loop_deted == true)) {
- pr_info("%s: sync power: CHGIN(0x%x), VB(0x%x), REG(%d)\n",
+ pr_debug("%s: sync power: CHGIN(0x%x), VB(0x%x), REG(%d)\n",
__func__, chgin_dtls, vbvolt,
chg_data->reg_loop_deted);
} else {
pr_err("%s: async power: CHGIN(0x%x), VB(0x%x), REG(%d)\n",
__func__, chgin_dtls, vbvolt,
chg_data->reg_loop_deted);
+ chg_det_erred = true;
/* check chargable input power */
if ((chgin_dtls == 0x0) &&
@@ -728,12 +736,24 @@ static int max77693_get_cable_type(struct max77693_charger_data *chg_data)
((vbvolt == 0x0) && (chgtyp != 0x00))) {
pr_info("%s: VB(0x%x), CHGTYP(0x%x)\n",
__func__, vbvolt, chgtyp);
- goto chg_det_err;
+
+ /* check D+/D- ovp */
+ dxovp = ((mu_st2 & MAX77693_DXOVP) >>
+ MAX77693_DXOVP_SHIFT);
+ if (dxovp) {
+ pr_err("%s: D+/D- ovp state\n", __func__);
+ chg_det_erred = true;
+ state = POWER_SUPPLY_TYPE_USB;
+ goto chg_det_finish;
+ } else {
+ pr_err("%s: async power and chgtyp\n", __func__);
+ goto chg_det_err;
+ }
}
/* charger type ok */
if (chg_det_erred)
- pr_info("%s: chgtyp detect ok, "
+ pr_err("%s: chgtyp detect ok, "
"CHGIN(0x%x). MU_ST2(0x%x), "
"CDR(0x%x), VB(0x%x), CHGTYP(0x%x)\n",
__func__, chgin_dtls, mu_st2,
@@ -789,7 +809,13 @@ chg_det_err:
}
chg_det_finish:
- pr_info("%s: cable type(%d)\n", __func__, state);
+ if (chg_det_erred)
+ pr_err("%s: cable type(%d)\n", __func__, state);
+
+ /* if cable is nothing, clear soft reg state flag */
+ if (state == POWER_SUPPLY_TYPE_BATTERY)
+ chg_data->soft_reg_state = false;
+
chg_data->cable_type = state;
mutex_unlock(&chg_data->ops_lock);
@@ -803,20 +829,20 @@ static int max77693_get_battery_state(struct max77693_charger_data *chg_data)
int state;
int vbus_state;
int chg_state;
+ bool low_bat = false;
u8 reg_data;
pr_debug("%s\n", __func__);
max77693_read_reg(i2c, MAX77693_CHG_REG_CHG_DTLS_01, &reg_data);
reg_data = ((reg_data & MAX77693_BAT_DTLS) >> MAX77693_BAT_DTLS_SHIFT);
-#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
- pr_info("%s: BAT_DTLS(0x%02x)\n", __func__, reg_data);
-#else
pr_debug("%s: BAT_DTLS(0x%02x)\n", __func__, reg_data);
-#endif
switch (reg_data) {
case 0x01:
- state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+ pr_info("%s: battery is okay "
+ "but its voltage is low(~VPQLB)\n", __func__);
+ low_bat = true;
+ state = POWER_SUPPLY_HEALTH_GOOD;
break;
case 0x02:
pr_info("%s: battery dead\n", __func__);
@@ -827,7 +853,8 @@ static int max77693_get_battery_state(struct max77693_charger_data *chg_data)
break;
case 0x04:
pr_info("%s: battery is okay "
- "but its voltage is low\n", __func__);
+ "but its voltage is low(VPQLB~VSYSMIN)\n", __func__);
+ low_bat = true;
state = POWER_SUPPLY_HEALTH_GOOD;
break;
case 0x05:
@@ -850,7 +877,7 @@ static int max77693_get_battery_state(struct max77693_charger_data *chg_data)
if (vbus_state == POWER_SUPPLY_VBUS_OVLO) {
pr_info("%s: vbus ovp\n", __func__);
state = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
- } else if ((reg_data == 0x4) &&
+ } else if ((low_bat == true) &&
(chg_state == POWER_SUPPLY_STATUS_FULL)) {
pr_info("%s: battery terminal error\n", __func__);
state = POWER_SUPPLY_HEALTH_UNDERVOLTAGE;
@@ -896,10 +923,6 @@ static void max77693_charger_reg_init(struct max77693_charger_data *chg_data)
reg_data = (1 << 7);
max77693_write_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_02, reg_data);
-#if defined(CONFIG_MACH_S2PLUS)
- /* top off current 200mA */
- reg_data = 0x04;
-#else
/*
* top off current 100mA
* top off timer 0min
@@ -908,7 +931,7 @@ static void max77693_charger_reg_init(struct max77693_charger_data *chg_data)
reg_data = (0x03 << 0); /* 125mA */
else
reg_data = (0x00 << 0); /* 100mA */
-#endif
+
reg_data |= (0x00 << 3);
max77693_write_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_03, reg_data);
@@ -921,15 +944,24 @@ static void max77693_charger_reg_init(struct max77693_charger_data *chg_data)
else
reg_data = (0xD6 << 0);
- /* For GC1 Model, MINVSYS is 3.4V*/
+ /*
+ * For GC1 Model, MINVSYS is 3.4V.
+ * For GC1 Model PRMV( Primary Charge Regn. Voltage) = 4.25V.
+ * Actual expected regulated voltage needs to be 4.2V but due to
+ * internal resistance and circuit deviation we need to set the
+ * benchmark a bit higher(4.25V).
+ */
#if defined(CONFIG_MACH_GC1)
- reg_data &= MAX77693_CHG_MINVSYS_MASK;
+ reg_data &= (~MAX77693_CHG_PRM_MASK);
+ reg_data |= (0x18 << MAX77693_CHG_PRM_SHIFT);
+ reg_data &= (~MAX77693_CHG_MINVSYS_MASK);
reg_data |= (0x4 << MAX77693_CHG_MINVSYS_SHIFT);
#endif
pr_info("%s: battery cv voltage %s, (sysrev %d)\n", __func__,
- (((reg_data & MAX77693_CHG_MINVSYS_MASK) == \
- (0x1D << 0)) ? "4.35V" : "4.2V"), system_rev);
+ (((reg_data & MAX77693_CHG_PRM_MASK) == \
+ (0x1D << MAX77693_CHG_PRM_SHIFT)) ? "4.35V" : "4.2V"),
+ system_rev);
max77693_write_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_04, reg_data);
@@ -937,38 +969,9 @@ static void max77693_charger_reg_init(struct max77693_charger_data *chg_data)
reg_data = 0x50;
max77693_write_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_11, reg_data);
-#if defined(CONFIG_MACH_S2PLUS)
- /* charging disable */
- reg_data = 0x00;
- max77693_write_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_00, reg_data);
-#endif
-
max77693_dump_reg(chg_data);
}
-#define SW_REG_CURR_STEP_MA 300
-static void max77693_soft_regulation(struct max77693_charger_data *chg_data)
-{
- struct i2c_client *i2c = chg_data->max77693->i2c;
- u8 reg_data;
- pr_info("%s\n", __func__);
-
- /* enable soft regulation loop */
- chg_data->soft_reg_state = true;
-
- max77693_read_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_09, &reg_data);
- reg_data &= MAX77693_CHG_CHGIN_LIM;
- chg_data->soft_reg_current = reg_data * 20;
- chg_data->soft_reg_current -= SW_REG_CURR_STEP_MA;
- chg_data->soft_reg_current = max(chg_data->soft_reg_current, 0);
- pr_info("%s: %dmA to %dmA\n", __func__,
- reg_data * 20, chg_data->soft_reg_current);
-
- reg_data = (chg_data->soft_reg_current / 20);
- pr_debug("%s: reg_data(0x%02x)\n", __func__, reg_data);
- max77693_write_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_09, reg_data);
-}
-
static void max77693_update_work(struct work_struct *work)
{
struct max77693_charger_data *chg_data = container_of(work,
@@ -1012,7 +1015,9 @@ static void max77693_update_work(struct work_struct *work)
vbus_state = max77693_get_vbus_state(chg_data);
if (vbus_state == POWER_SUPPLY_VBUS_WEAK) {
pr_info("%s: vbus weak\n", __func__);
- max77693_soft_regulation(chg_data);
+ wake_lock(&chg_data->softreg_wake_lock);
+ schedule_delayed_work(&chg_data->softreg_work,
+ msecs_to_jiffies(SW_REG_START_DELAY));
} else
pr_debug("%s: vbus not weak\n", __func__);
break;
@@ -1029,6 +1034,60 @@ static void max77693_update_work(struct work_struct *work)
wake_unlock(&chg_data->update_wake_lock);
}
+static void max77693_softreg_work(struct work_struct *work)
+{
+ struct max77693_charger_data *chg_data = container_of(work,
+ struct max77693_charger_data,
+ softreg_work.work);
+ struct i2c_client *i2c = chg_data->max77693->i2c;
+ u8 reg_data;
+ u8 int_ok, dtls_02, byp_dtls;
+ pr_info("%s\n", __func__);
+
+ mutex_lock(&chg_data->ops_lock);
+
+ max77693_read_reg(chg_data->max77693->i2c,
+ MAX77693_CHG_REG_CHG_INT_OK,
+ &int_ok);
+
+ max77693_read_reg(chg_data->max77693->i2c,
+ MAX77693_CHG_REG_CHG_DTLS_02,
+ &dtls_02);
+
+ byp_dtls = ((dtls_02 & MAX77693_BYP_DTLS) >>
+ MAX77693_BYP_DTLS_SHIFT);
+ pr_info("%s: INT_OK(0x%02x), BYP_DTLS(0x%02x)\n",
+ __func__, int_ok, byp_dtls);
+
+ if (byp_dtls & MAX77693_BYP_DTLS3) {
+ pr_info("%s: unstable power state for %dms\n", __func__,
+ SW_REG_START_DELAY);
+ /* enable soft regulation loop */
+ chg_data->soft_reg_state = true;
+
+ max77693_read_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_09, &reg_data);
+ reg_data &= MAX77693_CHG_CHGIN_LIM;
+ chg_data->soft_reg_current = reg_data * 20;
+ chg_data->soft_reg_current -= SW_REG_CURR_STEP_MA;
+ chg_data->soft_reg_current = max(chg_data->soft_reg_current, 0);
+ pr_info("%s: %dmA to %dmA\n", __func__,
+ reg_data * 20, chg_data->soft_reg_current);
+
+ reg_data = (chg_data->soft_reg_current / 20);
+ pr_debug("%s: reg_data(0x%02x)\n", __func__, reg_data);
+ max77693_write_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_09, reg_data);
+
+ wake_lock(&chg_data->softreg_wake_lock);
+ schedule_delayed_work(&chg_data->softreg_work,
+ msecs_to_jiffies(SW_REG_STEP_DELAY));
+ } else {
+ pr_info("%s: (recover) stable power\n", __func__);
+ wake_unlock(&chg_data->softreg_wake_lock);
+ }
+
+ mutex_unlock(&chg_data->ops_lock);
+}
+
/* Support property from charger */
static enum power_supply_property max77693_charger_props[] = {
POWER_SUPPLY_PROP_STATUS,
@@ -1154,7 +1213,9 @@ static irqreturn_t max77693_bypass_irq(int irq, void *data)
pr_err("%s: chgin regulation loop is active\n", __func__);
if (chg_data->cable_type != POWER_SUPPLY_TYPE_WIRELESS) {
/* software regulation */
- max77693_soft_regulation(chg_data);
+ wake_lock(&chg_data->softreg_wake_lock);
+ schedule_delayed_work(&chg_data->softreg_work,
+ msecs_to_jiffies(SW_REG_START_DELAY));
} else
pr_err("%s: now in wireless charging, "
" do not sw regulation\n", __func__);
@@ -1254,9 +1315,13 @@ static irqreturn_t wpc_charger_irq(int irq, void *data)
__func__);
s3c_gpio_setpull(chg_data->wc_v_gpio,
S3C_GPIO_PULL_NONE);
+ mutex_unlock(&chg_data->irq_lock);
enable_irq(chg_data->wc_v_irq);
+ mutex_lock(&chg_data->irq_lock);
} else if ((chg_data->wc_w_state == 1) && (wc_w_state == 0)) {
- disable_irq(chg_data->wc_v_irq);
+ mutex_unlock(&chg_data->irq_lock);
+ disable_irq_nosync(chg_data->wc_v_irq);
+ mutex_lock(&chg_data->irq_lock);
pr_info("%s: wpc deactivated, set V_INT as PD\n",
__func__);
s3c_gpio_setpull(chg_data->wc_v_gpio,
@@ -1392,6 +1457,8 @@ static __devinit int max77693_charger_probe(struct platform_device *pdev)
wake_lock_init(&chg_data->update_wake_lock, WAKE_LOCK_SUSPEND,
"charger-update");
+ wake_lock_init(&chg_data->softreg_wake_lock, WAKE_LOCK_SUSPEND,
+ "charger-softreg");
chg_data->charger_pdata = pdata->charger_data;
if (!pdata->charger_data->init_data)
@@ -1421,6 +1488,9 @@ static __devinit int max77693_charger_probe(struct platform_device *pdev)
INIT_DELAYED_WORK_DEFERRABLE(&chg_data->update_work,
max77693_update_work);
+ INIT_DELAYED_WORK_DEFERRABLE(&chg_data->softreg_work,
+ max77693_softreg_work);
+
ret = request_threaded_irq(chg_data->irq_bypass, NULL,
max77693_bypass_irq, 0, "bypass-irq", chg_data);
if (ret < 0)
@@ -1441,7 +1511,8 @@ static __devinit int max77693_charger_probe(struct platform_device *pdev)
#ifdef CONFIG_BATTERY_WPC_CHARGER
chg_data->wc_pwr_det = chg_data->charger_pdata->wc_pwr_det;
-#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1VZW)
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_GRANDE) || defined(CONFIG_MACH_IRON)
if (system_rev >= 0xA)
chg_data->wc_pwr_det = true;
#endif
@@ -1449,6 +1520,9 @@ static __devinit int max77693_charger_probe(struct platform_device *pdev)
if (system_rev >= 0x6)
chg_data->wc_pwr_det = true;
#endif
+#if defined(CONFIG_MACH_C2)
+ chg_data->wc_pwr_det = true;
+#endif
if (chg_data->wc_pwr_det)
pr_info("%s: support wc power detection\n", __func__);
@@ -1551,6 +1625,7 @@ wpc_init_finish:
err_kfree:
wake_lock_destroy(&chg_data->update_wake_lock);
+ wake_lock_destroy(&chg_data->softreg_wake_lock);
mutex_destroy(&chg_data->ops_lock);
mutex_destroy(&chg_data->irq_lock);
@@ -1563,6 +1638,7 @@ static int __devexit max77693_charger_remove(struct platform_device *pdev)
struct max77693_charger_data *chg_data = platform_get_drvdata(pdev);
wake_lock_destroy(&chg_data->update_wake_lock);
+ wake_lock_destroy(&chg_data->softreg_wake_lock);
mutex_destroy(&chg_data->ops_lock);
mutex_destroy(&chg_data->irq_lock);
diff --git a/drivers/battery/samsung_battery.c b/drivers/battery/samsung_battery.c
index dfd5d4a..d1cee8f 100644
--- a/drivers/battery/samsung_battery.c
+++ b/drivers/battery/samsung_battery.c
@@ -46,7 +46,6 @@ static char *supply_list[] = {
};
#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
-static void battery_notify_full_state(struct battery_info *info);
static bool battery_terminal_check_support(struct battery_info *info);
static void battery_error_control(struct battery_info *info);
#endif
@@ -111,14 +110,6 @@ static int battery_get_temper(struct battery_info *info)
temper = value.intval;
break;
case TEMPER_AP_ADC:
-#if defined(CONFIG_MACH_S2PLUS)
- if (system_rev < 2) {
- pr_info("%s: adc fixed as 30.0\n", __func__);
- temper = 300;
- mutex_unlock(&info->ops_lock);
- return temper;
- }
-#endif
#if defined(CONFIG_S3C_ADC)
adc = adc_max = adc_min = adc_total = 0;
for (cnt = 0; cnt < CNT_ADC_SAMPLE; cnt++) {
@@ -293,7 +284,14 @@ void battery_update_info(struct battery_info *info)
value.intval = SOC_TYPE_ADJUSTED;
info->psy_fuelgauge->get_property(info->psy_fuelgauge,
POWER_SUPPLY_PROP_CAPACITY, &value);
- info->battery_soc = value.intval;
+
+ if ((info->cable_type == POWER_SUPPLY_TYPE_BATTERY) &&
+ (info->battery_soc < value.intval) && (info->monitor_count))
+ pr_info("%s: new soc(%d) is bigger than prev soc(%d)"
+ " in discharging state\n", __func__,
+ value.intval, info->battery_soc);
+ else
+ info->battery_soc = value.intval;
value.intval = SOC_TYPE_RAW;
info->psy_fuelgauge->get_property(info->psy_fuelgauge,
@@ -301,12 +299,10 @@ void battery_update_info(struct battery_info *info)
info->battery_r_s_delta = value.intval - info->battery_raw_soc;
info->battery_raw_soc = value.intval;
-#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
value.intval = SOC_TYPE_FULL;
info->psy_fuelgauge->get_property(info->psy_fuelgauge,
POWER_SUPPLY_PROP_CAPACITY, &value);
info->battery_full_soc = value.intval;
-#endif
value.intval = VOLTAGE_TYPE_VCELL;
info->psy_fuelgauge->get_property(info->psy_fuelgauge,
@@ -355,7 +351,7 @@ update_finish:
break;
}
- pr_debug("%s: state(%d), type(%d), "
+ pr_info("%s: state(%d), type(%d), "
"health(%d), present(%d), "
"cable(%d), curr(%d), "
"soc(%d), raw(%d), "
@@ -382,19 +378,8 @@ void battery_control_info(struct battery_info *info,
case POWER_SUPPLY_PROP_CURRENT_MAX:
case POWER_SUPPLY_PROP_CURRENT_NOW:
#if defined(CONFIG_CHARGER_MAX8922_U1)
-#if defined(CONFIG_MACH_S2PLUS)
- if (system_rev >= 2) {
- info->psy_sub_charger->set_property(
- info->psy_sub_charger,
- property, &value);
- } else {
- info->psy_charger->set_property(info->psy_charger,
- property, &value);
- }
-#else
info->psy_sub_charger->set_property(info->psy_sub_charger,
property, &value);
-#endif
#else
info->psy_charger->set_property(info->psy_charger,
property, &value);
@@ -421,6 +406,20 @@ static void samsung_battery_alarm_start(struct alarm *alarm)
schedule_work(&info->monitor_work);
}
+static void battery_notify_full_state(struct battery_info *info)
+{
+ union power_supply_propval value;
+
+ if ((info->recharge_phase && info->full_charged_state) ||
+ ((info->battery_raw_soc > info->battery_full_soc) &&
+ (info->battery_soc == 100))) {
+ /* notify full state to fuel guage */
+ value.intval = POWER_SUPPLY_STATUS_FULL;
+ info->psy_fuelgauge->set_property(info->psy_fuelgauge,
+ POWER_SUPPLY_PROP_STATUS, &value);
+ }
+}
+
static void battery_monitor_interval(struct battery_info *info)
{
ktime_t interval, next, slack;
@@ -518,10 +517,16 @@ static bool battery_abstimer_cond(struct battery_info *info)
ktime = alarm_get_elapsed_realtime();
current_time = ktime_to_timespec(ktime);
- if (info->recharge_phase)
+ if (info->recharge_phase) {
abstimer_duration = info->pdata->abstimer_recharge_duration;
- else
- abstimer_duration = info->pdata->abstimer_charge_duration;
+ } else {
+ if (info->cable_type == POWER_SUPPLY_TYPE_WIRELESS)
+ abstimer_duration =
+ info->pdata->abstimer_charge_duration_wpc;
+ else
+ abstimer_duration =
+ info->pdata->abstimer_charge_duration;
+ }
if ((current_time.tv_sec - info->charge_start_time) >
abstimer_duration) {
@@ -1294,9 +1299,7 @@ monitor_finish:
/* icon indicator */
battery_indicator_icon(info);
-#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
battery_notify_full_state(info);
-#endif
/* dynamic battery polling interval */
battery_interval_calulation(info);
@@ -1426,20 +1429,6 @@ static void battery_error_work(struct work_struct *work)
}
#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
-static void battery_notify_full_state(struct battery_info *info)
-{
- union power_supply_propval value;
-
- if ((info->recharge_phase && info->full_charged_state) ||
- ((info->battery_raw_soc > info->battery_full_soc) &&
- (info->battery_soc == 100))) {
- /* notify full state to fuel guage */
- value.intval = POWER_SUPPLY_STATUS_FULL;
- info->psy_fuelgauge->set_property(info->psy_fuelgauge,
- POWER_SUPPLY_PROP_STATUS, &value);
- }
-}
-
static bool battery_terminal_check_support(struct battery_info *info)
{
int full_mode;
@@ -1724,11 +1713,8 @@ static __devinit int samsung_battery_probe(struct platform_device *pdev)
pr_info("%s: Recharge voltage: %d\n", __func__,
info->pdata->recharge_voltage);
#if defined(CONFIG_S3C_ADC)
-#if defined(CONFIG_MACH_S2PLUS)
- if (system_rev >= 2)
-#endif
- /* adc register */
- info->adc_client = s3c_adc_register(pdev, NULL, NULL, 0);
+ /* adc register */
+ info->adc_client = s3c_adc_register(pdev, NULL, NULL, 0);
if (IS_ERR(info->adc_client)) {
pr_err("%s: fail to register adc\n", __func__);
diff --git a/drivers/input/keyboard/cypress/cypress-touchkey.c b/drivers/input/keyboard/cypress/cypress-touchkey.c
index dde89e4..72a3422 100644
--- a/drivers/input/keyboard/cypress/cypress-touchkey.c
+++ b/drivers/input/keyboard/cypress/cypress-touchkey.c
@@ -590,6 +590,13 @@ static int touchkey_firmware_update(struct touchkey_i2c *tkey_i2c)
return TK_UPDATE_FAIL;
}
+ ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 3);
+ if (ret < 0) {
+ printk(KERN_DEBUG
+ "[TouchKey] i2c read fail. do not excute firm update.\n");
+ }
+ tkey_i2c->firmware_ver = data[1];
+ tkey_i2c->module_ver = data[2];
printk(KERN_DEBUG "[TouchKey] firm ver = %d, module ver = %d\n",
tkey_i2c->firmware_ver, tkey_i2c->module_ver);
} else {
@@ -640,6 +647,7 @@ static int touchkey_firmware_update(struct touchkey_i2c *tkey_i2c)
if (retry <= 0) {
tkey_i2c->pdata->power_on(0);
tkey_i2c->update_status = TK_UPDATE_FAIL;
+ ret = TK_UPDATE_FAIL;
}
} else {
if (tkey_i2c->firmware_ver >= 0x0A) {
@@ -1739,6 +1747,16 @@ static int i2c_touchkey_probe(struct i2c_client *client,
}
}
+ ret = touchkey_i2c_check(tkey_i2c);
+ if (ret < 0) {
+ printk(KERN_DEBUG
+ "[TouchKey] i2c read fail. do not excute firm update.\n");
+
+ input_unregister_device(input_dev);
+ touchkey_probe = false;
+ return -EBUSY;
+ }
+
ret =
request_threaded_irq(tkey_i2c->irq, NULL, touchkey_interrupt,
IRQF_DISABLED | IRQF_TRIGGER_FALLING |
@@ -1751,13 +1769,6 @@ static int i2c_touchkey_probe(struct i2c_client *client,
return -EBUSY;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
- tkey_i2c->early_suspend.suspend =
- (void *)sec_touchkey_early_suspend;
- tkey_i2c->early_suspend.resume =
- (void *)sec_touchkey_late_resume;
- register_early_suspend(&tkey_i2c->early_suspend);
-#endif
tkey_i2c->pdata->led_power_on(1);
@@ -1772,6 +1783,14 @@ static int i2c_touchkey_probe(struct i2c_client *client,
}
#endif
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ tkey_i2c->early_suspend.suspend =
+ (void *)sec_touchkey_early_suspend;
+ tkey_i2c->early_suspend.resume =
+ (void *)sec_touchkey_late_resume;
+ register_early_suspend(&tkey_i2c->early_suspend);
+#endif
+
#if defined(TK_HAS_AUTOCAL)
touchkey_autocalibration(tkey_i2c);
#endif
diff --git a/drivers/input/touchscreen/mms_ts.c b/drivers/input/touchscreen/mms_ts.c
index 058cc89..3b86885 100644
--- a/drivers/input/touchscreen/mms_ts.c
+++ b/drivers/input/touchscreen/mms_ts.c
@@ -3212,6 +3212,19 @@ static int __devinit mms_ts_probe(struct i2c_client *client,
#endif
touch_is_pressed = 0;
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1)
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ ret = gpio_get_value(GPIO_OLED_DET);
+ printk(KERN_DEBUG
+ "[TSP] OLED_DET = %d\n", ret);
+
+ if (ret == 0) {
+ printk(KERN_DEBUG
+ "[TSP] device wasn't connected to board\n");
+ return -EIO;
+ }
+#endif
+
if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
return -EIO;
diff --git a/drivers/leds/leds-aat1290a.c b/drivers/leds/leds-aat1290a.c
index 8889360..493f422 100644
--- a/drivers/leds/leds-aat1290a.c
+++ b/drivers/leds/leds-aat1290a.c
@@ -125,7 +125,7 @@ static long aat1290a_ioctl(struct file *file,
return 0;
}
-static ssize_t aat1290a_power(struct device *dev,
+ssize_t aat1290a_power(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
diff --git a/drivers/leds/leds-an30259a.c b/drivers/leds/leds-an30259a.c
index bae3203..ce05065 100644
--- a/drivers/leds/leds-an30259a.c
+++ b/drivers/leds/leds-an30259a.c
@@ -77,6 +77,7 @@
#define LED_R_CURRENT 0x28
#define LED_G_CURRENT 0x28
#define LED_B_CURRENT 0x28
+#define LED_MAX_CURRENT 0xFF
#define LED_OFF 0x00
#define MAX_NUM_LEDS 3
@@ -85,17 +86,17 @@ static struct an30259_led_conf led_conf[] = {
{
.name = "led_r",
.brightness = LED_OFF,
- .max_brightness = 0x3C,
+ .max_brightness = LED_R_CURRENT,
.flags = 0,
}, {
.name = "led_g",
.brightness = LED_OFF,
- .max_brightness = 0x3C,
+ .max_brightness = LED_G_CURRENT,
.flags = 0,
}, {
.name = "led_b",
.brightness = LED_OFF,
- .max_brightness = 0x3C,
+ .max_brightness = LED_B_CURRENT,
.flags = 0,
}
};
@@ -394,8 +395,20 @@ static void an30259a_set_led_blink(enum an30259a_led_enum led,
struct i2c_client *client;
client = b_client;
+ if (brightness == LED_OFF) {
+ leds_on(led, false, false, brightness);
+ return;
+ }
+
+ if (brightness > LED_MAX_CURRENT)
+ brightness = LED_MAX_CURRENT;
+
+ /* In user case, LED current is restricted to less than 2mA */
+ brightness = (brightness * LED_R_CURRENT) / LED_MAX_CURRENT + 1;
+
if (delay_on_time > SLPTT_MAX_VALUE)
delay_on_time = SLPTT_MAX_VALUE;
+
if (delay_off_time > SLPTT_MAX_VALUE)
delay_off_time = SLPTT_MAX_VALUE;
@@ -404,9 +417,6 @@ static void an30259a_set_led_blink(enum an30259a_led_enum led,
if (brightness == LED_OFF)
leds_on(led, false, false, brightness);
return;
- } else if (brightness == LED_OFF) {
- leds_on(led, false, false, brightness);
- return;
} else
leds_on(led, true, true, brightness);
diff --git a/drivers/media/video/s5c73m3.c b/drivers/media/video/s5c73m3.c
index ea07a34..5db5f7f 100644
--- a/drivers/media/video/s5c73m3.c
+++ b/drivers/media/video/s5c73m3.c
@@ -37,6 +37,7 @@
#endif
#include <linux/regulator/machine.h>
+#include <linux/leds-aat1290a.h>
#include <media/s5c73m3_platform.h>
#include "s5c73m3.h"
@@ -163,6 +164,8 @@ static u8 sysfs_phone_fw[10] = {0,};
static u8 sysfs_sensor_type[15] = {0,};
static u8 sysfs_isp_core[10] = {0,};
static u8 data_memory[500000] = {0,};
+static u32 crc_table[256] = {0,};
+static int copied_fw_binary;
static u16 isp_chip_info1;
static u16 isp_chip_info2;
@@ -312,6 +315,48 @@ static int s5c73m3_read(struct v4l2_subdev *sd,
return err;
}
+static int s5c73m3_i2c_check_status_with_CRC(struct v4l2_subdev *sd)
+{
+ int err = 0;
+ int index = 0;
+ u16 status = 0;
+ u16 i2c_status = 0;
+ u16 i2c_seq_status = 0;
+
+ do {
+ err = s5c73m3_read(sd, 0x0009, S5C73M3_STATUS, &status);
+ err = s5c73m3_read(sd, 0x0009,
+ S5C73M3_I2C_ERR_STATUS, &i2c_status);
+ if (i2c_status & ERROR_STATUS_CHECK_BIN_CRC) {
+ cam_dbg("failed to check CRC value of ISP Ram\n");
+ err = -1;
+ break;
+ }
+
+ if (status == 0xffff)
+ break;
+
+ index++;
+ udelay(500);
+ } while (index < 2000); /* 1 sec */
+
+ if (index >= 2000) {
+ err = s5c73m3_read(sd, 0x0009,
+ S5C73M3_I2C_ERR_STATUS, &i2c_status);
+ err = s5c73m3_read(sd, 0x0009,
+ S5C73M3_I2C_SEQ_STATUS, &i2c_seq_status);
+ cam_dbg("TimeOut!! index:%d,status:%#x,i2c_stauts:%#x,i2c_seq_status:%#x\n",
+ index,
+ status,
+ i2c_status,
+ i2c_seq_status);
+
+ err = -1;
+ }
+
+ return err;
+}
+
static int s5c73m3_i2c_check_status(struct v4l2_subdev *sd)
{
int err = 0;
@@ -346,6 +391,46 @@ static int s5c73m3_i2c_check_status(struct v4l2_subdev *sd)
return err;
}
+void s5c73m3_make_CRC_table(u32 *table, u32 id)
+{
+ u32 i, j, k;
+
+ for(i = 0; i < 256; ++i) {
+ k = i;
+ for(j = 0; j < 8; ++j) {
+ if(k & 1)
+ k = (k >> 1) ^ id;
+ else
+ k >>= 1;
+ }
+ table[i] = k;
+ }
+}
+
+static int s5c73m3_reset_module(struct v4l2_subdev *sd, bool powerReset)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err = 0;
+
+ cam_trace("E\n");
+
+ if (powerReset) {
+ err = state->pdata->power_on_off(0);
+ CHECK_ERR(err);
+ err = state->pdata->power_on_off(1);
+ CHECK_ERR(err);
+ } else {
+ err = state->pdata->is_isp_reset();
+ CHECK_ERR(err);
+ }
+ err = s5c73m3_set_timing_register_for_vdd(sd);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+
+ return err;
+}
+
static int s5c73m3_writeb(struct v4l2_subdev *sd,
unsigned short addr, unsigned short data)
{
@@ -487,6 +572,27 @@ static int s5c73m3_get_sensor_fw_binary(struct v4l2_subdev *sd)
mm_segment_t old_fs;
long ret = 0;
char fw_path[25] = {0,};
+ u8 mem0 =0, mem1 = 0;
+ u32 CRC = 0;
+ u32 DataCRC = 0;
+ u32 IntOriginalCRC = 0;
+ u32 crc_index = 0;
+ int retryCnt = 2;
+
+ if (state->sensor_fw[0] == 'O') {
+ sprintf(fw_path, "/data/cfw/SlimISP_G%c.bin",
+ state->sensor_fw[1]);
+ } else if (state->sensor_fw[0] == 'S') {
+ sprintf(fw_path, "/data/cfw/SlimISP_Z%c.bin",
+ state->sensor_fw[1]);
+ } else {
+ sprintf(fw_path, "/data/cfw/SlimISP_%c%c.bin",
+ state->sensor_fw[0],
+ state->sensor_fw[1]);
+ }
+
+ /* Make CRC Table */
+ s5c73m3_make_CRC_table((u32 *)&crc_table, 0xEDB88320);
/*ARM go*/
err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF);
@@ -554,32 +660,18 @@ static int s5c73m3_get_sensor_fw_binary(struct v4l2_subdev *sd)
mdelay(200);
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- if (state->sensor_fw[0] == 'O') {
- sprintf(fw_path, "/data/cfw/SlimISP_G%c.bin",
- state->sensor_fw[1]);
- } else if (state->sensor_fw[0] == 'S') {
- sprintf(fw_path, "/data/cfw/SlimISP_Z%c.bin",
- state->sensor_fw[1]);
- } else {
- sprintf(fw_path, "/data/cfw/SlimISP_%c%c.bin",
- state->sensor_fw[0],
- state->sensor_fw[1]);
- }
-
- fp = filp_open(fw_path, O_WRONLY|O_CREAT, 0644);
- if (IS_ERR(fp) || fp == NULL) {
- cam_err("failed to open %s, err %ld\n",
- fw_path, PTR_ERR(fp));
- err = -EINVAL;
- goto out;
- }
+retry:
+ memset(data_memory, 0, sizeof(data_memory));
+ mem0 =0, mem1 = 0;
+ CRC = 0;
+ DataCRC = 0;
+ IntOriginalCRC = 0;
+ crc_index = 0;
/* SPI Copy mode ready I2C CMD */
err = s5c73m3_writeb(sd, 0x0924, 0x0000);
CHECK_ERR(err);
+ cam_dbg("sent SPI ready CMD\n");
rxSize = 64*1024;
mdelay(10);
@@ -589,19 +681,72 @@ static int s5c73m3_get_sensor_fw_binary(struct v4l2_subdev *sd)
state->sensor_size, rxSize);
CHECK_ERR(err);
- ret = vfs_write(fp, (char __user *)data_memory,
- state->sensor_size, &fp->f_pos);
+ CRC = ~CRC;
+ for(crc_index = 0;crc_index < (state->sensor_size-4)/2;crc_index++) {
+ /*low byte*/
+ mem0 = (unsigned char)(data_memory[crc_index*2] & 0x00ff);
+ /*high byte*/
+ mem1 = (unsigned char)(data_memory[crc_index*2+1] & 0x00ff);
+ CRC = crc_table[(CRC ^ (mem0)) & 0xFF] ^ (CRC >> 8);
+ CRC = crc_table[(CRC ^ (mem1)) & 0xFF] ^ (CRC >> 8);
+ }
+ CRC = ~CRC;
+
+ DataCRC = (CRC&0x000000ff)<<24;
+ DataCRC += (CRC&0x0000ff00)<<8;
+ DataCRC += (CRC&0x00ff0000)>>8;
+ DataCRC += (CRC&0xff000000)>>24;
+ cam_err("made CSC value by S/W = 0x%x\n", DataCRC);
+
+ IntOriginalCRC = (data_memory[state->sensor_size-4]&0x00ff)<<24;
+ IntOriginalCRC += (data_memory[state->sensor_size-3]&0x00ff)<<16;
+ IntOriginalCRC += (data_memory[state->sensor_size-2]&0x00ff)<<8;
+ IntOriginalCRC += (data_memory[state->sensor_size-1]&0x00ff);
+ cam_err("Original CRC Int = 0x%x\n", IntOriginalCRC);
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ if (IntOriginalCRC == DataCRC) {
+ fp = filp_open(fw_path, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ if (IS_ERR(fp) || fp == NULL) {
+ cam_err("failed to open %s, err %ld\n",
+ fw_path, PTR_ERR(fp));
+ err = -EINVAL;
+ goto out;
+ }
+
+ ret = vfs_write(fp, (char __user *)data_memory,
+ state->sensor_size, &fp->f_pos);
+
+ if (camfw_info[S5C73M3_SD_CARD].opened == 0) {
+ memcpy(state->phone_fw,
+ state->sensor_fw,
+ S5C73M3_FW_VER_LEN);
+ state->phone_fw[S5C73M3_FW_VER_LEN+1] = ' ';
+
+ memcpy(sysfs_phone_fw,
+ state->phone_fw,
+ sizeof(state->phone_fw));
+ cam_dbg("Changed to Phone_version = %s\n",
+ state->phone_fw);
+ }
+ } else {
+ if (retryCnt > 0) {
+ set_fs(old_fs);
+ retryCnt--;
+ goto retry;
+ }
+ }
if (fp != NULL)
filp_close(fp, current->files);
out:
set_fs(old_fs);
-
return err;
}
-
static int s5c73m3_get_sensor_fw_version(struct v4l2_subdev *sd)
{
struct s5c73m3_state *state = to_state(sd);
@@ -802,7 +947,6 @@ static int s5c73m3_get_phone_fw_version(struct v4l2_subdev *sd)
int err = 0;
int retVal = 0;
int fw_requested = 1;
- int copied_fw_binary = 0;
if (state->sensor_fw[0] == 'O') {
sprintf(fw_path, "SlimISP_G%c.bin",
@@ -885,14 +1029,12 @@ request_fw:
state->fw_index = S5C73M3_IN_DATA;
}
} else {
- cam_dbg("get new fw to F-ROM : %s Version\n",
+ cam_dbg("can't open %s Ver. Firmware. so, download from F-ROM\n",
state->sensor_fw);
if (fw != NULL)
release_firmware(fw);
- retVal = state->pdata->is_isp_reset();
- CHECK_ERR(retVal);
- retVal = s5c73m3_set_timing_register_for_vdd(sd);
+ retVal = s5c73m3_reset_module(sd, true);
CHECK_ERR(retVal);
retVal = s5c73m3_get_sensor_fw_binary(sd);
CHECK_ERR(retVal);
@@ -901,17 +1043,13 @@ request_fw:
}
}
- if (copied_fw_binary) {
+ if (!copied_fw_binary) {
memcpy(state->phone_fw,
- state->sensor_fw,
+ camfw_info[state->fw_index].ver,
S5C73M3_FW_VER_LEN);
state->phone_fw[S5C73M3_FW_VER_LEN+1] = ' ';
- } else {
- memcpy(state->phone_fw,
- camfw_info[state->fw_index].ver,
- S5C73M3_FW_VER_LEN);
- state->phone_fw[S5C73M3_FW_VER_LEN+1] = ' ';
}
+
memcpy(sysfs_phone_fw,
state->phone_fw,
sizeof(state->phone_fw));
@@ -1049,10 +1187,11 @@ static int s5c73m3_check_fw_date(struct v4l2_subdev *sd)
static int s5c73m3_check_fw(struct v4l2_subdev *sd, int download)
{
- struct s5c73m3_state *state = to_state(sd);
int err, i;
int retVal;
+ copied_fw_binary = 0;
+
if (!download) {
for (i = 0; i < S5C73M3_PATH_MAX; i++)
camfw_info[i].opened = 0;
@@ -1065,16 +1204,22 @@ static int s5c73m3_check_fw(struct v4l2_subdev *sd, int download)
}
retVal = s5c73m3_check_fw_date(sd);
- err = state->pdata->is_isp_reset();
- CHECK_ERR(err);
- err = s5c73m3_set_timing_register_for_vdd(sd);
- CHECK_ERR(err);
/* retVal = 0 : Same Version
- retVal < 0 : Phone Version is latest Version than sensorFW.
- retVal > 0 : Sensor Version is latest version than phoenFW. */
- if (retVal <= 0 || download) {
+ retVal < 0 : Phone Version is latest Version than sensorFW.
+ retVal > 0 : Sensor Version is latest version than phoenFW. */
+ if (retVal <= 0||download) {
cam_dbg("Loading From PhoneFW......\n");
+
+ /* In case that there is no FW in phone and FW needs to be
+ downloaded from F-ROM, ISP power reset is required before
+ loading FW to ISP for F-ROM to work properly.*/
+ if (copied_fw_binary)
+ err = s5c73m3_reset_module(sd, true);
+ else
+ err = s5c73m3_reset_module(sd, false);
+ CHECK_ERR(err);
+
err = s5c73m3_SPI_booting(sd);
CHECK_ERR(err);
@@ -1084,26 +1229,13 @@ static int s5c73m3_check_fw(struct v4l2_subdev *sd, int download)
}
} else {
cam_dbg("Loading From SensorFW......\n");
-#if 0
- err = s5c73m3_SPI_booting_by_ISP(sd);
+ err = s5c73m3_reset_module(sd, true);
CHECK_ERR(err);
-#else
err = s5c73m3_get_sensor_fw_binary(sd);
CHECK_ERR(err);
-
- memcpy(state->phone_fw,
- state->sensor_fw,
- S5C73M3_FW_VER_LEN);
- state->phone_fw[S5C73M3_FW_VER_LEN+1] = ' ';
-
- memcpy(sysfs_phone_fw,
- state->phone_fw,
- sizeof(state->phone_fw));
- cam_dbg("Changed to Phone_version = %s\n",
- state->phone_fw);
-#endif
}
+
return 0;
}
@@ -1927,6 +2059,27 @@ static int s5c73m3_aeawb_lock_unlock(struct v4l2_subdev *sd, int val)
return 0;
}
+static void s5c73m3_wait_for_preflash_fire(struct v4l2_subdev *sd)
+{
+ u16 pre_flash = false;
+ u16 timeout_cnt = 0;
+
+ do {
+ s5c73m3_read(sd, 0x0009,
+ S5C73M3_STILL_PRE_FLASH | 0x5000, &pre_flash);
+ if (pre_flash || timeout_cnt > 20) {
+ if (!pre_flash) {
+ cam_dbg("pre_Flash = %d, timeout_cnt = %d\n",
+ pre_flash, timeout_cnt);
+ }
+ break;
+ } else
+ timeout_cnt++;
+
+ mdelay(15);
+ } while (1);
+}
+
static int s5c73m3_start_capture(struct v4l2_subdev *sd, int val)
{
struct s5c73m3_state *state = to_state(sd);
@@ -1940,7 +2093,7 @@ static int s5c73m3_start_capture(struct v4l2_subdev *sd, int val)
if (!pre_flash) {
err = s5c73m3_writeb(sd, S5C73M3_STILL_PRE_FLASH
, S5C73M3_STILL_PRE_FLASH_FIRE);
- msleep(100);
+ s5c73m3_wait_for_preflash_fire(sd);
}
err = s5c73m3_writeb(sd, S5C73M3_STILL_MAIN_FLASH
, S5C73M3_STILL_MAIN_FLASH_FIRE);
@@ -1954,7 +2107,7 @@ static int s5c73m3_start_capture(struct v4l2_subdev *sd, int val)
if (isneed_flash) {
err = s5c73m3_writeb(sd, S5C73M3_STILL_PRE_FLASH
, S5C73M3_STILL_PRE_FLASH_FIRE);
- msleep(100);
+ s5c73m3_wait_for_preflash_fire(sd);
err = s5c73m3_writeb(sd,
S5C73M3_STILL_MAIN_FLASH,
S5C73M3_STILL_MAIN_FLASH_FIRE);
@@ -3109,7 +3262,7 @@ static int s5c73m3_read_vdd_core(struct v4l2_subdev *sd)
set_fs(KERNEL_DS);
fp = filp_open(S5C73M3_CORE_VDD,
- O_WRONLY|O_CREAT, 0666);
+ O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (IS_ERR(fp))
goto out;
@@ -3197,34 +3350,31 @@ static int s5c73m3_init(struct v4l2_subdev *sd, u32 val)
#endif
CHECK_ERR(err);
- err = s5c73m3_i2c_check_status(sd);
+ err = s5c73m3_i2c_check_status_with_CRC(sd);
if (err < 0) {
cam_err("ISP is not ready. retry loading fw!!\n");
/* retry */
retVal = s5c73m3_check_fw_date(sd);
- err = state->pdata->is_isp_reset();
- CHECK_ERR(err);
- err = s5c73m3_set_timing_register_for_vdd(sd);
- CHECK_ERR(err);
-
/* retVal = 0 : Same Version
retVal < 0 : Phone Version is latest Version than sensorFW.
retVal > 0 : Sensor Version is latest version than phoenFW. */
if (retVal <= 0) {
cam_dbg("Loading From PhoneFW......\n");
+ err = s5c73m3_reset_module(sd, false);
+ CHECK_ERR(err);
err = s5c73m3_SPI_booting(sd);
CHECK_ERR(err);
} else {
cam_dbg("Loading From SensorFW......\n");
+ err = s5c73m3_reset_module(sd, true);
+ CHECK_ERR(err);
err = s5c73m3_get_sensor_fw_binary(sd);
CHECK_ERR(err);
}
-
}
state->isp.bad_fw = 0;
-
s5c73m3_init_param(sd);
return 0;
@@ -3271,18 +3421,7 @@ static ssize_t s5c73m3_camera_rear_flash(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
- int err;
-
- if (buf[0] == '0')
- err = s5c73m3_writeb(sd_internal, S5C73M3_FLASH_TORCH,
- S5C73M3_FLASH_TORCH_OFF);
- else
- err = s5c73m3_writeb(sd_internal, S5C73M3_FLASH_TORCH,
- S5C73M3_FLASH_TORCH_ON);
-
- CHECK_ERR(err);
-
- return count;
+ return aat1290a_power(dev, attr, buf, count);
}
static ssize_t s5c73m3_camera_isp_core_show(struct device *dev,
diff --git a/drivers/media/video/s5c73m3.h b/drivers/media/video/s5c73m3.h
index 97a697b..40d7eaf 100644
--- a/drivers/media/video/s5c73m3.h
+++ b/drivers/media/video/s5c73m3.h
@@ -450,10 +450,10 @@ struct s5c73m3_state {
#define ERR_STATUS_FROM_INIT (1<<0x4)
#define ERR_STATUS_I2C_CIS_STREAM_OFF (1<<0x5)
#define ERR_STATUS_I2C_N_CMD_OVER (1<<0x6)
-#define ERR_STATUS_I2C_N_CMD_MISMATCH0 (1<<0x7)
-#define ERR_STATUS_I2C_N_CMD_MISMATCH1 (1<<0x8)
-#define ERR_STATUS_EXCEPTION (1<<0x9)
-
+#define ERROR_STATUS_I2C_N_CMD_MISMATCH (1<<0x7)
+#define ERROR_STATUS_CHECK_BIN_CRC (1<<0x8)
+#define ERROR_STATUS_EXCEPTION (1<<0x9)
+#define ERROR_STATUS_INIF_INIT_STATE (0x8)
#ifdef CONFIG_VIDEO_S5C73M3_SPI
extern int s5c73m3_spi_write(const u8 *addr, const int len, const int txSize);
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h
index 97fc4cb..2d8f3b7 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h
@@ -40,6 +40,7 @@
#define FIMG2D_BITBLT_BLIT _IOWR(FIMG2D_IOCTL_MAGIC, 0, struct fimg2d_blit)
#define FIMG2D_BITBLT_SYNC _IOW(FIMG2D_IOCTL_MAGIC, 1, int)
#define FIMG2D_BITBLT_VERSION _IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version)
+#define FIMG2D_BITBLT_SECURE _IOW(FIMG2D_IOCTL_MAGIC, 3, unsigned int)
struct fimg2d_version {
unsigned int hw;
@@ -483,8 +484,8 @@ struct fimg2d_control {
struct resource *mem;
void __iomem *regs;
- bool err;
int irq;
+ unsigned int secure;
atomic_t nctx;
atomic_t busy;
atomic_t active;
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x.h b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x.h
index 9165d6f..4bf8f74 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x.h
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x.h
@@ -172,6 +172,7 @@ struct fimg2d_blend_coeff {
enum fimg2d_coeff d_coeff;
};
+void fimg2d4x_sw_reset(struct fimg2d_control *info);
void fimg2d4x_reset(struct fimg2d_control *info);
void fimg2d4x_enable_irq(struct fimg2d_control *info);
void fimg2d4x_disable_irq(struct fimg2d_control *info);
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c
index 9a4f8ad..fc6016c 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c
@@ -38,7 +38,9 @@ static inline void fimg2d4x_blit_wait(struct fimg2d_control *info, struct fimg2d
fimg2d_dump_command(cmd);
if (!fimg2d4x_blit_done_status(info))
- info->err = true; /* device error */
+ printk(KERN_ERR "[%s] G2D operation is not finished", __func__);
+
+ fimg2d4x_sw_reset(info);
}
}
@@ -63,19 +65,16 @@ void fimg2d4x_bitblt(struct fimg2d_control *info)
fimg2d_clk_on(info);
while (1) {
+ spin_lock(&info->bltlock);
cmd = fimg2d_get_first_command(info);
if (!cmd) {
- spin_lock(&info->bltlock);
atomic_set(&info->active, 0);
spin_unlock(&info->bltlock);
break;
}
+ spin_unlock(&info->bltlock);
ctx = cmd->ctx;
- if (info->err) {
- printk(KERN_ERR "[%s] device error\n", __func__);
- goto blitend;
- }
atomic_set(&info->busy, 1);
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c
index 8135ecd..4eb4d04 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c
@@ -28,6 +28,17 @@ static const int msk_oprmode = (int)MSK_ARGB;
static const int premult_round_mode = (int)PREMULT_ROUND_1; /* (A+1)*B) >> 8 */
static const int blend_round_mode = (int)BLEND_ROUND_0; /* (A+1)*B) >> 8 */
+void fimg2d4x_sw_reset(struct fimg2d_control *info)
+{
+ wr(FIMG2D_SOFT_RESET, FIMG2D_SOFT_RESET_REG);
+ /* turn off wince option */
+ wr(0x0, FIMG2D_BLEND_FUNCTION_REG);
+
+ /* set default repeat mode to reflect(mirror) */
+ wr(FIMG2D_SRC_REPEAT_REFLECT, FIMG2D_SRC_REPEAT_MODE_REG);
+ wr(FIMG2D_MSK_REPEAT_REFLECT, FIMG2D_MSK_REPEAT_MODE_REG);
+}
+
void fimg2d4x_reset(struct fimg2d_control *info)
{
#ifdef SOFT_RESET_ENABLED
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c
index 26ea56b..eaa722c 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c
@@ -295,16 +295,20 @@ int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx,
if (copy_from_user(&cmd->image[i], buf[i],
sizeof(struct fimg2d_image))) {
if ((blit->dst) && (type == ADDR_USER))
- if (!down_write_trylock(&page_alloc_slow_rwsem))
- return -EAGAIN;
+ if (!down_write_trylock(&page_alloc_slow_rwsem)) {
+ ret = -EAGAIN;
+ goto err_user;
+ }
ret = -EFAULT;
goto err_user;
}
}
if ((blit->dst) && (type == ADDR_USER))
- if (!down_write_trylock(&page_alloc_slow_rwsem))
- return -EAGAIN;
+ if (!down_write_trylock(&page_alloc_slow_rwsem)) {
+ ret = -EAGAIN;
+ goto err_user;
+ }
cmd->ctx = ctx;
cmd->op = blit->op;
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c
index 6ae4d6e..ed14901 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c
@@ -38,8 +38,14 @@
#include "fimg2d_clk.h"
#include "fimg2d_ctx.h"
#include "fimg2d_helper.h"
+#include "fimg2d_cache.h"
#define CTX_TIMEOUT msecs_to_jiffies(1000)
+#define LV1_SHIFT 20
+#define LV2_BASE_MASK 0x3ff
+#define LV2_PT_MASK 0xff000
+#define LV2_SHIFT 12
+#define LV1_DESC_MASK 0x3
static struct fimg2d_control *info;
@@ -58,7 +64,13 @@ static DECLARE_WORK(fimg2d_work, fimg2d_worker);
static irqreturn_t fimg2d_irq(int irq, void *dev_id)
{
fimg2d_debug("irq\n");
- info->stop(info);
+ if (!atomic_read(&info->clkon)) {
+ fimg2d_clk_on(info);
+ info->stop(info);
+ fimg2d_clk_off(info);
+ } else {
+ info->stop(info);
+ }
return IRQ_HANDLED;
}
@@ -67,6 +79,8 @@ static int fimg2d_sysmmu_fault_handler(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
unsigned long pgtable_base, unsigned long fault_addr)
{
struct fimg2d_bltcmd *cmd;
+ unsigned long *pgd;
+ unsigned long *lv1d, *lv2d;
if (itype == SYSMMU_PAGEFAULT) {
printk(KERN_ERR "[%s] sysmmu page fault(0x%lx), pgd(0x%lx)\n",
@@ -91,11 +105,20 @@ static int fimg2d_sysmmu_fault_handler(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
fimg2d_dump_command(cmd);
+ pgd = (unsigned long *)cmd->ctx->mm->pgd;
+ lv1d = pgd + (fault_addr >> LV1_SHIFT);
+ printk(KERN_ERR " Level 1 descriptor(0x%lx)\n", *lv1d);
+ if ((*lv1d & LV1_DESC_MASK) != 0x1) {
+ fimg2d_clean_outer_pagetable(cmd->ctx->mm, fault_addr, 4);
+ goto next;
+ }
+
+ lv2d = (unsigned long *)phys_to_virt(*lv1d & ~LV2_BASE_MASK) +
+ ((fault_addr & LV2_PT_MASK) >> LV2_SHIFT);
+ printk(KERN_ERR " Level 2 descriptor(0x%lx)\n", *lv2d);
+ fimg2d_clean_outer_pagetable(cmd->ctx->mm, fault_addr, 4);
next:
- fimg2d_clk_dump(info);
- info->dump(info);
- BUG();
return 0;
}
@@ -106,8 +129,6 @@ static void fimg2d_context_wait(struct fimg2d_context *ctx)
atomic_set(&info->active, 1);
queue_work(info->work_q, &fimg2d_work);
printk(KERN_ERR "[%s] ctx %p cmd wait timeout\n", __func__, ctx);
- if (info->err)
- break;
}
}
}
@@ -188,11 +209,8 @@ static long fimg2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
switch (cmd) {
case FIMG2D_BITBLT_BLIT:
- if (info->err) {
- printk(KERN_ERR "[%s] device error, do sw fallback\n",
- __func__);
+ if (info->secure)
return -EFAULT;
- }
if (copy_from_user(&blit, (void *)arg, sizeof(blit)))
return -EFAULT;
@@ -245,6 +263,24 @@ static long fimg2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return -EFAULT;
break;
+ case FIMG2D_BITBLT_SECURE:
+ if (copy_from_user(&info->secure,
+ (unsigned int *)arg,
+ sizeof(unsigned int))) {
+ printk(KERN_ERR
+ "[%s] failed to FIMG2D_BITBLT_SECURE: copy_from_user error\n\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ while (1) {
+ if (fimg2d_queue_is_empty(&info->cmd_q))
+ break;
+ mdelay(2);
+ }
+
+ break;
+
default:
printk(KERN_ERR "[%s] unknown ioctl\n", __func__);
ret = -EFAULT;
@@ -278,6 +314,7 @@ static int fimg2d_setup_controller(struct fimg2d_control *info)
atomic_set(&info->busy, 0);
atomic_set(&info->nctx, 0);
atomic_set(&info->active, 0);
+ info->secure = 0;
spin_lock_init(&info->bltlock);
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c
index 74a18e8..eef839f 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c
@@ -15,6 +15,8 @@
#include "mali_osk.h"
#include "mali_kernel_common.h"
+#include "mali_pmm.h"
+#include "mali_pmm_state.h"
/* needed to detect kernel version specific code */
#include <linux/version.h>
@@ -65,6 +67,11 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size )
/* OPT Recycling of notification objects */
_mali_osk_notification_wrapper_t *notification;
+ if (MALI_PMM_NOTIFICATION_TYPE == type) {
+ if (size != sizeof(mali_pmm_message_t))
+ return NULL;
+ }
+
notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size, GFP_KERNEL );
if (NULL == notification)
{
diff --git a/drivers/media/video/samsung/mfc5x/mfc_dec.c b/drivers/media/video/samsung/mfc5x/mfc_dec.c
index 6e0645d..fd78b7d 100644
--- a/drivers/media/video/samsung/mfc5x/mfc_dec.c
+++ b/drivers/media/video/samsung/mfc5x/mfc_dec.c
@@ -2388,6 +2388,12 @@ int mfc_exec_decoding(struct mfc_inst_ctx *ctx, union mfc_args *args)
offset = CheckMPEG4StartCode(stream_vir+consumed,
dec_ctx->streamsize - consumed);
+
+ if (offset == -1) {
+ mfc_warn("No start code in remained bitstream: %d\n", offset);
+ return ret;
+ }
+
if (offset > 4)
consumed += offset;
diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c
index 7af8a15..68508e7 100644
--- a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c
+++ b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c
@@ -953,8 +953,11 @@ static int s5p_tvout_tvif_release(struct file *file)
tvout_dbg("on_stop_process(%d)\n", on_stop_process);
atomic_dec(&s5p_tvout_v4l2_private.tvif_use);
- if (atomic_read(&s5p_tvout_v4l2_private.tvif_use) == 0)
+ if (atomic_read(&s5p_tvout_v4l2_private.tvif_use) == 0) {
+ s5p_tvout_mutex_lock();
s5p_tvif_ctrl_stop();
+ s5p_tvout_mutex_unlock();
+ }
on_stop_process = false;
tvout_dbg("on_stop_process(%d)\n", on_stop_process);
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c
index 323c13c..07fbd3f 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c
@@ -142,10 +142,10 @@ static int os_allocate(void* ctx, ump_dd_mem * descriptor)
if (is_cached)
{
- new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN );
+ new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN );
} else
{
- new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN | __GFP_COLD);
+ new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN | __GFP_COLD);
}
if (NULL == new_page)
{
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index e505132..bb89b20 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1008,12 +1008,11 @@ static int mmc_blk_err_check(struct mmc_card *card,
brq->data.error) {
#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_P4NOTE) || \
defined(CONFIG_MACH_C1_USA_ATT)
- /* dh0421.hwang */
if (mmc_card_mmc(card)) {
- printk(KERN_ERR "[TEST] brq->sbc.opcode=%d,"
+ pr_err("brq->sbc.opcode=%d,"
"brq->cmd.opcode=%d.\n",
brq->sbc.opcode, brq->cmd.opcode);
- printk(KERN_ERR "[TEST] brq->sbc.error=%d,"
+ pr_err("brq->sbc.error=%d,"
"brq->cmd.error=%d, brq->stop.error=%d,"
"brq->data.error=%d.\n", brq->sbc.error,
brq->cmd.error, brq->stop.error,
@@ -1934,35 +1933,21 @@ snd_packed_rd:
#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_P4NOTE) || \
defined(CONFIG_MACH_C1_USA_ATT)
/*
- * dh0421.hwang
* It's for Engineering DEBUGGING only
* This has to be removed before PVR(guessing)
* Please refer mshci reg dumps
*/
if (mmc_card_mmc(card) && status != 3) {
- printk(KERN_ERR "[TEST] CMD aborting case in"
+ pr_err("CMD aborting case in "
"MMC's block layer ret %d.\n", ret);
- printk(KERN_ERR "%s: CMD%d, ARG=0x%x.\n",
+ pr_err("%s: CMD%d, ARG=0x%x.\n",
req->rq_disk->disk_name,
brq->cmd.opcode,
brq->cmd.arg);
- printk(KERN_ERR "[TEST] If PACKED_NONE,"
- "confirm end_request done\n");
- printk(KERN_ERR "packed CMD type = %d.\n",
+ pr_err("packed CMD type = %d.\n",
mq_rq ? mq_rq->packed_cmd : -1);
- printk(KERN_ERR "[TEST] mmc%d, request returns %d.\n",
+ pr_err("mmc%d, request returns %d.\n",
card->host->index, status);
- printk(KERN_ERR "[TEST] err means...\n");
- printk(KERN_ERR "\t1: MMC_BLK_PARTIAL.\n");
- printk(KERN_ERR "\t2: MMC_BLK_CMD_ERR.\n");
- printk(KERN_ERR "\t3: MMC_BLK_RETRY.\n");
- printk(KERN_ERR "\t4: MMC_BLK_ABORT.\n");
- printk(KERN_ERR "\t5: MMC_BLK_DATA_ERR.\n");
- printk(KERN_ERR "\t6: MMC_BLK_ECC_ERR.\n");
- if (!rqc) {
- panic("[TEST] mmc%d, returns %d.\n",
- card->host->index, status);
- }
}
#endif
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 8051835..0b2b5b4 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2373,12 +2373,9 @@ int mmc_flush_cache(struct mmc_card *card)
(card->ext_csd.cache_ctrl & 1)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_FLUSH_CACHE, 1, 0);
- if (err) {
+ if (err)
pr_err("%s: cache flush error %d\n",
mmc_hostname(card->host), err);
- panic("[TEST] mmc%d, %s returns %d.\n",
- host->index, __func__, err);
- }
}
return err;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index d118f3b..596098b 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -28,9 +28,11 @@
#define MMC_RETRY_READ_EXT_CSD
#else
/* For debugging about ext_csd register value */
+#if 0
#define MMC_CHECK_EXT_CSD
#endif
#endif
+#endif
static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
@@ -208,15 +210,6 @@ static void mmc_error_ext_csd(struct mmc_card *card, u8 *ext_csd,
}
memcpy(ext_csd_backup, ext_csd, 512);
-#if 0 /* Just checking */
-#define EXT_CSD_REV 192 /* RO */
-#define EXT_CSD_STRUCTURE 194 /* RO */
-#define EXT_CSD_CARD_TYPE 196 /* RO */
-#endif
- pr_err("[TEST] eMMC check : %d, %d, %d.\n",
- ext_csd_backup[EXT_CSD_REV],
- ext_csd_backup[EXT_CSD_STRUCTURE],
- ext_csd_backup[EXT_CSD_CARD_TYPE]);
} else {
ext_csd_new = kmalloc(512, GFP_KERNEL);
if (!ext_csd_new) {
@@ -225,12 +218,12 @@ static void mmc_error_ext_csd(struct mmc_card *card, u8 *ext_csd,
} else {
err = mmc_send_ext_csd(card, ext_csd_new);
if (err)
- pr_err("[TEST] Fail to get new EXT_CSD.\n");
+ pr_err("Fail to get new EXT_CSD.\n");
else
available_new = 1;
}
- pr_err("[TEST] %s: starting diff ext_csd.\n", __func__);
- pr_err("[TEST] %s: error on slice %d: backup=%d, now=%d,"
+ pr_err("%s: starting diff ext_csd.\n", __func__);
+ pr_err("%s: error on slice %d: backup=%d, now=%d,"
"new=%d.\n",
__func__, slice,
ext_csd_backup[slice], ext_csd[slice],
@@ -384,62 +377,104 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
mmc_card_set_blockaddr(card);
}
card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
- switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
- case EXT_CSD_CARD_TYPE_SDR_ALL:
- case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V:
- case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V:
- case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52:
- card->ext_csd.hs_max_dtr = 200000000;
- card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200;
- break;
- case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL:
- case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V:
- case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V:
- case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52:
- card->ext_csd.hs_max_dtr = 200000000;
- card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V;
- break;
- case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL:
- case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V:
- case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V:
- case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52:
- card->ext_csd.hs_max_dtr = 200000000;
- card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V;
- break;
- case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 |
- EXT_CSD_CARD_TYPE_26:
- card->ext_csd.hs_max_dtr = 52000000;
- card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52;
- break;
- case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 |
- EXT_CSD_CARD_TYPE_26:
- card->ext_csd.hs_max_dtr = 52000000;
- card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V;
- break;
- case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 |
- EXT_CSD_CARD_TYPE_26:
- card->ext_csd.hs_max_dtr = 52000000;
- card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V;
- break;
- case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
- card->ext_csd.hs_max_dtr = 52000000;
- break;
- case EXT_CSD_CARD_TYPE_26:
- card->ext_csd.hs_max_dtr = 26000000;
- break;
- default:
+ if (card->host->caps2 & MMC_CAP2_HS200) {
+ switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
+ case EXT_CSD_CARD_TYPE_SDR_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200;
+ break;
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V;
+ break;
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V;
+ break;
+ case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 |
+ EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 52000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52;
+ break;
+ case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 |
+ EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 52000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V;
+ break;
+ case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 |
+ EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 52000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V;
+ break;
+ case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 52000000;
+ break;
+ case EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 26000000;
+ break;
+ default:
#if defined(MMC_CHECK_EXT_CSD)
- /* For debugging about ext_csd register value */
- mmc_error_ext_csd(card, ext_csd, 0, EXT_CSD_CARD_TYPE);
+ /* For debugging about ext_csd register value */
+ mmc_error_ext_csd(card, ext_csd, 0, EXT_CSD_CARD_TYPE);
#endif
- /* MMC v4 spec says this cannot happen */
- printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
- "support any high-speed modes.\n",
- mmc_hostname(card->host));
+ /* MMC v4 spec says this cannot happen */
+ printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
+ "support any high-speed modes.\n",
+ mmc_hostname(card->host));
#if defined(MMC_RETRY_READ_EXT_CSD)
- err = -EINVAL;
- goto out;
+ err = -EINVAL;
+ goto out;
#endif
+ }
+ } else {
+ pr_debug("%s: Ignore device type HS200.\n",
+ mmc_hostname(card->host));
+ switch (ext_csd[EXT_CSD_CARD_TYPE] &
+ EXT_CSD_CARD_TYPE_NO_HS200_MASK) {
+ case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 |
+ EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 52000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52;
+ break;
+ case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 |
+ EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 52000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V;
+ break;
+ case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 |
+ EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 52000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V;
+ break;
+ case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 52000000;
+ break;
+ case EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 26000000;
+ break;
+ default:
+#if defined(MMC_CHECK_EXT_CSD)
+ /* For debugging about ext_csd register value */
+ mmc_error_ext_csd(card, ext_csd, 0, EXT_CSD_CARD_TYPE);
+#endif
+ /* MMC v4 spec says this cannot happen */
+ printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
+ "support any high-speed modes.\n",
+ mmc_hostname(card->host));
+#if defined(MMC_RETRY_READ_EXT_CSD)
+ err = -EINVAL;
+ goto out;
+#endif
+ }
}
card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT];
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 4586eaa..e4271fa 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -934,7 +934,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
if (!mmc_host_is_spi(host)) {
err = mmc_send_relative_addr(host, &card->rca);
if (err)
- return err;
+ goto free_card;
mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
}
@@ -942,7 +942,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
if (!oldcard) {
err = mmc_sd_get_csd(host, card);
if (err)
- return err;
+ goto free_card;
mmc_decode_cid(card);
}
@@ -953,7 +953,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
if (!mmc_host_is_spi(host)) {
err = mmc_select_card(card);
if (err)
- return err;
+ goto free_card;
}
err = mmc_sd_setup_card(host, card, oldcard != NULL);
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 26e42d8..979cf0b 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -1058,9 +1058,6 @@ static const struct mmc_bus_ops mmc_sdio_ops = {
.alive = mmc_sdio_alive,
};
-#if defined(CONFIG_MACH_M0) && defined(CONFIG_TARGET_LOCALE_EUR)
-extern void print_epll_con0(void);
-#endif
/*
* Starting point for SDIO card init.
*/
@@ -1077,11 +1074,6 @@ int mmc_attach_sdio(struct mmc_host *host)
if (err)
return err;
-#if defined(CONFIG_MACH_M0) && defined(CONFIG_TARGET_LOCALE_EUR)
- /* a sdio module is detected. print EPLL */
- print_epll_con0();
-#endif
-
mmc_attach_bus(host, &mmc_sdio_ops);
if (host->ocr_avail_sdio)
host->ocr_avail = host->ocr_avail_sdio;
diff --git a/drivers/mmc/host/mshci-s3c.c b/drivers/mmc/host/mshci-s3c.c
index 323f115..5023d10 100644
--- a/drivers/mmc/host/mshci-s3c.c
+++ b/drivers/mmc/host/mshci-s3c.c
@@ -487,6 +487,13 @@ static int __devinit mshci_s3c_probe(struct platform_device *pdev)
if (pdata->cd_type == S3C_MSHCI_CD_PERMANENT) {
host->quirks |= MSHCI_QUIRK_BROKEN_PRESENT_BIT;
host->mmc->caps |= MMC_CAP_NONREMOVABLE;
+ if (pdata->int_power_gpio) {
+ gpio_set_value(pdata->int_power_gpio, 1);
+ s3c_gpio_cfgpin(pdata->int_power_gpio,
+ S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(pdata->int_power_gpio,
+ S3C_GPIO_PULL_NONE);
+ }
}
/* IF SD controller's WP pin donsn't connected with SD card and there
diff --git a/drivers/mmc/host/mshci.c b/drivers/mmc/host/mshci.c
index 73de297..9431405 100644
--- a/drivers/mmc/host/mshci.c
+++ b/drivers/mmc/host/mshci.c
@@ -1620,7 +1620,6 @@ static void mshci_cmd_irq(struct mshci_host *host, u32 intmask)
host->error_state = 1;
#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_P4NOTE) || \
defined(CONFIG_MACH_C1_USA_ATT)
- /* dh0421.hwang */
if (host->mmc && host->mmc->card)
mshci_dumpregs(host);
#endif
@@ -1662,11 +1661,8 @@ static void mshci_data_irq(struct mshci_host *host, u32 intmask, u8 intr_src)
printk(KERN_ERR "%s: Host timeout error\n",
mmc_hostname(host->mmc));
host->data->error = -ETIMEDOUT;
-#if 1 /* debugging for Host timeout error */
+ /* debugging for Host timeout error */
mshci_dumpregs(host);
- panic("[TEST] %s: HTO error interrupt occured\n",
- mmc_hostname(host->mmc));
-#endif
} else if (intmask & INTMSK_DRTO) {
printk(KERN_ERR "%s: Data read timeout error\n",
mmc_hostname(host->mmc));
@@ -1709,7 +1705,6 @@ static void mshci_data_irq(struct mshci_host *host, u32 intmask, u8 intr_src)
host->error_state = 1;
#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_P4NOTE) || \
defined(CONFIG_MACH_C1_USA_ATT)
- /* dh0421.hwang */
if (host->mmc && host->mmc->card)
mshci_dumpregs(host);
#endif
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile
index 15d6c7c..1a27ef0 100644
--- a/drivers/net/wireless/bcmdhd/Makefile
+++ b/drivers/net/wireless/bcmdhd/Makefile
@@ -1,7 +1,7 @@
# bcmdhd
DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \
-DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DWLBTAMP -DBCMFILEIMAGE \
- -DDHDTHREAD -DDHD_GPL -DDHD_SCHED -DDHD_DEBUG -DBDC -DTOE \
+ -DDHDTHREAD -DDHD_GPL -DDHD_SCHED -DDHD_DEBUG -DBDC \
-DDHD_BCMEVENTS -DSHOW_EVENTS -DDONGLEOVERLAYS -DBCMDBG \
-DCUSTOMER_HW_SAMSUNG -DOOB_INTR_ONLY \
-DMMC_SDIO_ABORT -DBCMSDIO -DBCMLXSDMMC -DBCMPLATFORM_BUS -DWLP2P \
@@ -84,7 +84,7 @@ endif
# For SLP feature
ifeq ($(CONFIG_SLP),y)
-DHDCFLAGS += -DSLP_PATH -DWRITE_MACADDR
+DHDCFLAGS += -DSLP_PATH -DWRITE_MACADDR -DCUSTOMER_HW_SLP
endif
# 5GHz channels setting
diff --git a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c
index 42433d6..f7676d8 100644
--- a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c
+++ b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c
@@ -49,6 +49,10 @@ extern void dhdsdio_isr(void * args);
#include <dhd.h>
#endif /* defined(OOB_INTR_ONLY) */
+#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
+/*SLP_wakelock_alternative_code*/
+struct device *pm_dev;
+#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */
/**
* SDIO Host Controller info
*/
@@ -162,6 +166,9 @@ int bcmsdh_probe(struct device *dev)
int irq = 0;
uint32 vendevid;
unsigned long irq_flags = 0;
+#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
+ int ret = 0;
+#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */
#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
pdev = to_platform_device(dev);
@@ -228,6 +235,12 @@ int bcmsdh_probe(struct device *dev)
sdhc->next = sdhcinfo;
sdhcinfo = sdhc;
+#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
+ /*SLP_wakelock_alternative_code*/
+ pm_dev=sdhc->dev;
+ ret = device_init_wakeup(pm_dev, 1);
+ printf("%s : device_init_wakeup(pm_dev) enable, ret = %d\n", __func__, ret);
+#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */
/* Read the vendor/device ID from the CIS */
vendevid = bcmsdh_query_device(sdh);
/* try to attach to the target device */
@@ -261,6 +274,11 @@ int bcmsdh_remove(struct device *dev)
osl_t *osh;
sdhc = sdhcinfo;
+#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
+ /*SLP_wakelock_alternative_code*/
+ device_init_wakeup(pm_dev, 0);
+ printf("%s : device_init_wakeup(pm_dev) disable\n", __func__);
+#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */
drvinfo.detach(sdhc->ch);
bcmsdh_detach(sdhc->osh, sdhc->sdh);
diff --git a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c
index 9687141..83c1192 100644
--- a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c
+++ b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c
@@ -200,6 +200,9 @@ static int bcmsdh_sdmmc_suspend(struct device *pdev)
#endif /* defined(OOB_INTR_ONLY) */
#endif /* defined(OOB_INTR_ONLY) */
dhd_mmc_suspend = TRUE;
+#if defined (CUSTOMER_HW_SAMSUNG) && defined (CONFIG_ARCH_TEGRA)
+ irq_set_irq_wake(390, 1);
+#endif
smp_mb();
return 0;
@@ -218,7 +221,11 @@ static int bcmsdh_sdmmc_resume(struct device *pdev)
if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata()))
bcmsdh_oob_intr_set(1);
#endif /* (OOB_INTR_ONLY) */
-#endif /* (OOB_INTR_ONLY) */
+#endif /* !CUSTOMER_HW_SAMSUNG */
+#if defined (CUSTOMER_HW_SAMSUNG) && defined (CONFIG_ARCH_TEGRA)
+ if (func->num == 2)
+ irq_set_irq_wake(390, 0);
+#endif
smp_mb();
return 0;
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h
index 3b7f026..5095aba 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h
@@ -83,7 +83,11 @@ enum dhd_bus_state {
#define CONCURRENT_MASK (STA_MASK | WFD_MASK)
/* max sequential rxcntl timeouts to set HANG event */
+#ifdef BCM4334_CHIP
+#define MAX_CNTL_TIMEOUT 1
+#else
#define MAX_CNTL_TIMEOUT 2
+#endif
#define DHD_SCAN_ACTIVE_TIME 40 /* ms : Embedded default Active setting from DHD Driver */
#define DHD_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD Driver */
@@ -258,9 +262,6 @@ typedef struct dhd_pub {
int hang_was_sent;
int rxcnt_timeout; /* counter rxcnt timeout to send HANG */
int txcnt_timeout; /* counter txcnt timeout to send HANG */
-#ifdef BCM4334_CHIP
- int tx_seq_badcnt;
-#endif
#ifdef WLMEDIA_HTSF
uint8 htsfdlystat_sz; /* Size of delay stats, max 255B */
#endif
@@ -638,7 +639,11 @@ extern uint dhd_radio_up;
/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */
extern int dhd_idletime;
+#ifdef DHD_USE_IDLECOUNT
+#define DHD_IDLETIME_TICKS 5
+#else
#define DHD_IDLETIME_TICKS 1
+#endif /* DHD_USE_IDLECOUNT */
/* SDIO Drive Strength */
extern uint dhd_sdiod_drive_strength;
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c
index 73760ef..c0ef0bd 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c
@@ -507,10 +507,6 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
int i;
#endif
-#ifdef PASS_ALL_MCAST_PKTS
- char iovbuf[20];
- uint32 allmultivar = 0;
-#endif
/* Figure out powermode 1 or o command */
strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1);
@@ -530,13 +526,6 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
0, dhd_master_mode);
}
-
-#ifdef PASS_ALL_MCAST_PKTS
- allmultivar = 1;
- bcm_mkiovar("allmulti", (char *)&allmultivar, 4, iovbuf, sizeof(iovbuf));
- dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
- WL_ERR(("DHCP is progressing , allmulti value = %d \n", allmultivar));
-#endif /* PASS_ALL_MCAST_PKTS */
}
#endif
@@ -594,13 +583,6 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
1, dhd_master_mode);
}
-
-#ifdef PASS_ALL_MCAST_PKTS
- allmultivar = 0;
- bcm_mkiovar("allmulti", (char *)&allmultivar, 4, iovbuf, sizeof(iovbuf));
- dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
- WL_ERR(("DHCP is complete , allmulti value = %d \n", allmultivar));
-#endif /* PASS_ALL_MCAST_PKTS */
}
#endif
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c
index 956c4e1..f9f8c20 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c
@@ -267,36 +267,13 @@ int
dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set, int ifindex)
{
wl_ioctl_t ioc;
-#ifdef CUSTOMER_HW_SAMSUNG
- int ret;
-#endif /* CUSTOMER_HW_SAMSUNG */
ioc.cmd = cmd;
ioc.buf = arg;
ioc.len = len;
ioc.set = set;
-#ifdef CUSTOMER_HW_SAMSUNG
- ret = dhd_wl_ioctl(dhd_pub, ifindex, &ioc, arg, len);
- if (ret < 0) {
- if (ioc.cmd == WLC_GET_VAR) {
- DHD_ERROR(("%s: WLC_GET_VAR: %s, error = %d\n",
- __FUNCTION__, (char *)ioc.buf, ret));
- } else if (ioc.cmd == WLC_SET_VAR) {
- char pkt_filter[] = "pkt_filter_add";
- if (strncmp(pkt_filter, ioc.buf, sizeof(pkt_filter)) != 0) {
- DHD_ERROR(("%s: WLC_SET_VAR: %s, error = %d\n",
- __FUNCTION__, (char *)ioc.buf, ret));
- }
- } else {
- DHD_ERROR(("%s: WLC_IOCTL: cmd:%d, error = %d\n",
- __FUNCTION__, ioc.cmd, ret));
- }
- }
- return ret;
-#else
return dhd_wl_ioctl(dhd_pub, ifindex, &ioc, arg, len);
-#endif /* CUSTOMER_HW_SAMSUNG */
}
@@ -308,14 +285,26 @@ dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int le
dhd_os_proto_block(dhd_pub);
ret = dhd_prot_ioctl(dhd_pub, ifindex, ioc, buf, len);
-#ifdef BCM4334_CHIP
- if (!ret || ret == -ETIMEDOUT || (dhd_pub->tx_seq_badcnt >= 2))
-#else
- if (!ret || ret == -ETIMEDOUT)
-#endif
+ if (!ret || ret == -ETIMEDOUT) {
+ /* Send hang event only if dhd_open() was success */
+ if (dhd_pub->up)
dhd_os_check_hang(dhd_pub, ifindex, ret);
+ }
dhd_os_proto_unblock(dhd_pub);
+#ifdef CUSTOMER_HW_SAMSUNG
+ if (ret < 0) {
+ if (ioc->cmd == WLC_GET_VAR)
+ DHD_ERROR(("%s: WLC_GET_VAR: %s, error = %d\n",
+ __FUNCTION__, (char *)ioc->buf, ret));
+ else if (ioc->cmd == WLC_SET_VAR)
+ DHD_ERROR(("%s: WLC_SET_VAR: %s, error = %d\n",
+ __FUNCTION__, (char *)ioc->buf, ret));
+ else
+ DHD_ERROR(("%s: WLC_IOCTL: cmd: %d, error = %d\n",
+ __FUNCTION__, ioc->cmd, ret));
+ }
+#endif /* CUSTOMER_HW_SAMSUNG */
return ret;
}
@@ -586,10 +575,8 @@ dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec)
if (pktq_pfull(q, prec))
eprec = prec;
else if (pktq_full(q)) {
-#if defined(BCMASSERT_LOG)
p = pktq_peek_tail(q, &eprec);
- ASSERT(p);
-#endif
+// ASSERT(p);
if (eprec > prec || eprec < 0)
return FALSE;
}
@@ -608,11 +595,9 @@ dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec)
PKTFREE(dhdp->osh, p, TRUE);
}
-#if defined(BCMASSERT_LOG)
/* Enqueue */
p = pktq_penq(q, prec, pkt);
- ASSERT(p);
-#endif
+// ASSERT(p);
return TRUE;
}
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c
index 2e80890..4ef1dcb 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c
@@ -1,3 +1,19 @@
+/* Function list
+ 1. Module Type
+ a. For CID - Use 'USE_CID_CHECK' Feature
+ dhd_write_cid_file(), dhd_dump_cis(), dhd_check_module_cid()
+ b. For MAC - Use 'GET_MAC_FROM_OTP' Feature
+ dhd_write_mac_file(), dhd_check_module_mac()
+ 2. COB Type
+ a. For MAC - Use 'READ_MACADDR' Feature
+ dhd_read_macaddr()
+ 3. Etc
+ a. Power Save Mode - Use 'CONFIG_CONTROL_PM' Feature
+ sec_control_pm()
+ b. U1 Module only - Use 'WRITE_MACADDR' Feature
+ dhd_write_macaddr
+*/
+
#include <typedefs.h>
#include <linuxver.h>
#include <osl.h>
@@ -21,6 +37,9 @@ extern int _dhd_set_mac_address(struct dhd_info *dhd,
#define MACINFO "/opt/etc/.mac.info"
#define REVINFO "/data/.rev"
#else
+#define MACINFO "/data/.mac.info"
+#define MACINFO_EFS "/efs/wifi/.mac.info"
+#define NVMACINFO "/data/.nvmac.info"
#define REVINFO "/data/.rev"
#define CIDINFO "/data/.cid.info"
#define PSMINFO "/data/.psm.info"
@@ -34,21 +53,21 @@ int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
mm_segment_t oldfs = {0};
char randommac[3] = {0};
char buf[18] = {0};
- char *filepath = "/efs/wifi/.mac.info";
+ char *filepath_efs = MACINFO_EFS;
#ifdef CONFIG_TARGET_LOCALE_VZW
char *nvfilepath = "/data/misc/wifi/.nvmac.info";
#else
- char *nvfilepath = "/data/.nvmac.info";
+ char *nvfilepath = NVMACINFO;
#endif
int ret = 0;
- fp = filp_open(filepath, O_RDONLY, 0);
+ fp = filp_open(filepath_efs, O_RDONLY, 0);
if (IS_ERR(fp)) {
start_readmac:
/* File Doesn't Exist. Create and write mac addr.*/
- fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
+ fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
if (IS_ERR(fp)) {
- DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs));
return -1;
}
oldfs = get_fs();
@@ -64,9 +83,9 @@ start_readmac:
if (fp->f_mode & FMODE_WRITE) {
ret = fp->f_op->write(fp, (const char *)macbuffer, sizeof(macbuffer), &fp->f_pos);
if (ret < 0)
- DHD_ERROR(("[WIFI]MAC address [%s] Failed to write into File: %s\n", macbuffer, filepath));
+ DHD_ERROR(("[WIFI]MAC address [%s] Failed to write into File: %s\n", macbuffer, filepath_efs));
else
- DHD_ERROR(("[WIFI]MAC address [%s] written into File: %s\n", macbuffer, filepath));
+ DHD_ERROR(("[WIFI]MAC address [%s] written into File: %s\n", macbuffer, filepath_efs));
}
set_fs(oldfs);
/* Reading the MAC Address from .mac.info file( the existed file or just created file)*/
@@ -90,7 +109,7 @@ start_readmac:
(unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]),
(unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5]));
else
- DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath));
+ DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath_efs));
if (fp)
filp_close(fp, NULL);
@@ -119,8 +138,8 @@ enum {
int dhd_write_rdwr_macaddr(struct ether_addr *mac)
{
- char *filepath_old = "/data/.mac.info";
- char *filepath = "/efs/wifi/.mac.info";
+ char *filepath_data = MACINFO;
+ char *filepath_efs = MACINFO_EFS;
struct file *fp_mac = NULL;
char buf[18] = {0};
mm_segment_t oldfs = {0};
@@ -134,9 +153,9 @@ int dhd_write_rdwr_macaddr(struct ether_addr *mac)
mac->octet[3], mac->octet[4], mac->octet[5]);
/* /data/.mac.info will be created */
- fp_mac = filp_open(filepath_old, O_RDWR | O_CREAT, 0666);
+ fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666);
if (IS_ERR(fp_mac)) {
- DHD_ERROR(("[WIFI] %s: File open error\n", filepath_old));
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_data));
return -1;
} else {
oldfs = get_fs();
@@ -147,18 +166,18 @@ int dhd_write_rdwr_macaddr(struct ether_addr *mac)
sizeof(buf), &fp_mac->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI] Mac address [%s] Failed"
- " to write into File: %s\n", buf, filepath_old));
+ " to write into File: %s\n", buf, filepath_data));
else
DHD_INFO(("[WIFI] Mac address [%s] written"
- " into File: %s\n", buf, filepath_old));
+ " into File: %s\n", buf, filepath_data));
}
set_fs(oldfs);
filp_close(fp_mac, NULL);
}
/* /efs/wifi/.mac.info will be created */
- fp_mac = filp_open(filepath, O_RDWR | O_CREAT, 0666);
+ fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
if (IS_ERR(fp_mac)) {
- DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs));
return -1;
} else {
oldfs = get_fs();
@@ -169,10 +188,10 @@ int dhd_write_rdwr_macaddr(struct ether_addr *mac)
sizeof(buf), &fp_mac->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI] Mac address [%s] Failed"
- " to write into File: %s\n", buf, filepath));
+ " to write into File: %s\n", buf, filepath_efs));
else
DHD_INFO(("[WIFI] Mac address [%s] written"
- " into File: %s\n", buf, filepath));
+ " into File: %s\n", buf, filepath_efs));
}
set_fs(oldfs);
filp_close(fp_mac, NULL);
@@ -190,12 +209,12 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
char macbuffer[18] = {0};
char randommac[3] = {0};
char buf[18] = {0};
- char *filepath_old = "/data/.mac.info";
- char *filepath = "/efs/wifi/.mac.info";
+ char *filepath_data = MACINFO;
+ char *filepath_efs = MACINFO_EFS;
#ifdef CONFIG_TARGET_LOCALE_NA
char *nvfilepath = "/data/misc/wifi/.nvmac.info";
#else
- char *nvfilepath = "/data/.nvmac.info";
+ char *nvfilepath = NVMACINFO;
#endif
char cur_mac[128] = {0};
char dummy_mac[ETHER_ADDR_LEN] = {0x00, 0x90, 0x4C, 0xC5, 0x12, 0x38};
@@ -231,7 +250,7 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
cur_mac[0], cur_mac[1], cur_mac[2],
cur_mac[3], cur_mac[4], cur_mac[5]);
- fp_mac = filp_open(filepath_old, O_RDONLY, 0);
+ fp_mac = filp_open(filepath_data, O_RDONLY, 0);
if (IS_ERR(fp_mac)) { /* file does not exist */
/* read mac is the dummy mac (00:90:4C:C5:12:38) */
if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0)
@@ -280,7 +299,7 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
}
}
}
- fp_mac = filp_open(filepath, O_RDONLY, 0);
+ fp_mac = filp_open(filepath_efs, O_RDONLY, 0);
if (IS_ERR(fp_mac)) { /* file does not exist */
/* read mac is the dummy mac (00:90:4C:C5:12:38) */
if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0)
@@ -402,18 +421,18 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
mm_segment_t oldfs = {0};
char randommac[3] = {0};
char buf[18] = {0};
- char *filepath = "/efs/wifi/.mac.info";
+ char *filepath_efs = MACINFO_EFS;
int is_zeromac = 0;
int ret = 0;
/* MAC address copied from efs/wifi.mac.info */
- fp = filp_open(filepath, O_RDONLY, 0);
+ fp = filp_open(filepath_efs, O_RDONLY, 0);
if (IS_ERR(fp)) {
/* File Doesn't Exist. Create and write mac addr.*/
- fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
+ fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
if (IS_ERR(fp)) {
DHD_ERROR(("[WIFI] %s: File open error\n",
- filepath));
+ filepath_efs));
return -1;
}
@@ -438,11 +457,11 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
if (ret < 0)
DHD_ERROR(("[WIFI] Mac address [%s]"
" Failed to write into File:"
- " %s\n", macbuffer, filepath));
+ " %s\n", macbuffer, filepath_efs));
else
DHD_ERROR(("[WIFI] Mac address [%s]"
" written into File: %s\n",
- macbuffer, filepath));
+ macbuffer, filepath_efs));
}
set_fs(oldfs);
} else {
@@ -473,7 +492,7 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
(unsigned int *)&(mac->octet[5]));
else
DHD_INFO(("dhd_bus_start: Reading from the"
- " '%s' returns 0 bytes\n", filepath));
+ " '%s' returns 0 bytes\n", filepath_efs));
if (fp)
filp_close(fp, NULL);
@@ -494,16 +513,16 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
#endif /* RDWR_KORICS_MACADDR */
#ifdef USE_CID_CHECK
-static int dhd_write_cid_file(const char *filepath, const char *buf, int buf_len)
+static int dhd_write_cid_file(const char *filepath_efs, const char *buf, int buf_len)
{
struct file *fp = NULL;
mm_segment_t oldfs = {0};
int ret = 0;
/* File is always created.*/
- fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
+ fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
if (IS_ERR(fp)) {
- DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs));
return -1;
} else {
oldfs = get_fs();
@@ -513,10 +532,10 @@ static int dhd_write_cid_file(const char *filepath, const char *buf, int buf_len
ret = fp->f_op->write(fp, buf, buf_len, &fp->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI] Failed to write CIS[%s]"
- " into '%s'\n", buf, filepath));
+ " into '%s'\n", buf, filepath_efs));
else
DHD_ERROR(("[WIFI] CID [%s] written into"
- " '%s'\n", buf, filepath));
+ " '%s'\n", buf, filepath_efs));
}
set_fs(oldfs);
}
@@ -664,7 +683,7 @@ static int dhd_write_mac_file(const char *filepath, const char *buf, int buf_len
fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
/*File is always created.*/
if (IS_ERR(fp)) {
- DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
+ DHD_ERROR(("[WIFI] File open error\n"));
return -1;
} else {
oldfs = get_fs();
@@ -673,11 +692,9 @@ static int dhd_write_mac_file(const char *filepath, const char *buf, int buf_len
if (fp->f_mode & FMODE_WRITE) {
ret = fp->f_op->write(fp, buf, buf_len, &fp->f_pos);
if (ret < 0)
- DHD_ERROR(("[WIFI] Failed to write CIS[%s]\
-into '%s'\n", buf, filepath));
+ DHD_ERROR(("[WIFI] Failed to write CIS. \n"));
else
- DHD_ERROR(("[WIFI] MAC [%s] written\
-into '%s'\n", buf, filepath));
+ DHD_ERROR(("[WIFI] MAC written. \n"));
}
set_fs(oldfs);
}
@@ -693,19 +710,13 @@ int dhd_check_module_mac(dhd_pub_t *dhd)
int ret = -1;
unsigned char cis_buf[250] = {0};
unsigned char mac_buf[20] = {0};
- const char *macfilepath = "/efs/wifi/.mac.info";
+ unsigned char otp_mac_buf[20] = {0};
+ const char *macfilepath = MACINFO_EFS;
/* Try reading out from CIS */
cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
struct file *fp_mac = NULL;
- fp_mac = filp_open(macfilepath, O_RDONLY, 0);
- if (!IS_ERR(fp_mac)) {
- kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf));
- DHD_ERROR(("[WIFI].mac.info file already exist : [%s]\n",
- mac_buf));
- return 0;
- }
cish->source = 0;
cish->byteoff = 0;
cish->nbytes = sizeof(cis_buf);
@@ -716,6 +727,7 @@ int dhd_check_module_mac(dhd_pub_t *dhd)
if (ret < 0) {
DHD_ERROR(("%s: CIS reading failed, err=%d\n", __func__,
ret));
+ return ret;
} else {
unsigned char mac_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#ifdef DUMP_CIS
@@ -728,11 +740,21 @@ int dhd_check_module_mac(dhd_pub_t *dhd)
mac_id[4] = cis_buf[CIS_MAC_OFFSET + 4];
mac_id[5] = cis_buf[CIS_MAC_OFFSET + 5];
- sprintf(mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
mac_id[0], mac_id[1], mac_id[2], mac_id[3], mac_id[4],
mac_id[5]);
- DHD_ERROR(("[WIFI]mac_id is setted from OTP: [%s]\n", mac_buf));
- dhd_write_mac_file(macfilepath, mac_buf, sizeof(mac_buf));
+ DHD_ERROR(("[WIFI]mac_id is setted from OTP \n"));
+ }
+
+ fp_mac = filp_open(macfilepath, O_RDONLY, 0);
+ if (!IS_ERR(fp_mac)) {
+ DHD_ERROR(("[WIFI]Check Mac address in .mac.info \n"));
+ kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf));
+
+ if (strncmp(mac_buf , otp_mac_buf , 17) != 0) {
+ DHD_ERROR(("[WIFI]file MAC is wrong. Write OTP MAC in .mac.info \n"));
+ dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf));
+ }
}
return ret;
@@ -742,8 +764,8 @@ int dhd_check_module_mac(dhd_pub_t *dhd)
#ifdef WRITE_MACADDR
int dhd_write_macaddr(struct ether_addr *mac)
{
- char *filepath_old = "/data/.mac.info";
- char *filepath = "/efs/wifi/.mac.info";
+ char *filepath_data = MACINFO;
+ char *filepath_efs = MACINFO_EFS;
struct file *fp_mac = NULL;
char buf[18] = {0};
@@ -758,10 +780,10 @@ startwrite:
mac->octet[3], mac->octet[4], mac->octet[5]);
/* File will be created /data/.mac.info. */
- fp_mac = filp_open(filepath_old, O_RDWR | O_CREAT, 0666);
+ fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666);
if (IS_ERR(fp_mac)) {
- DHD_ERROR(("[WIFI] %s: File open error\n", filepath_old));
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_data));
return -1;
} else {
oldfs = get_fs();
@@ -772,16 +794,16 @@ startwrite:
sizeof(buf), &fp_mac->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI] Mac address [%s] Failed to"
- " write into File: %s\n", buf, filepath_old));
+ " write into File: %s\n", buf, filepath_data));
else
DHD_INFO(("[WIFI] Mac address [%s] written"
- " into File: %s\n", buf, filepath_old));
+ " into File: %s\n", buf, filepath_data));
}
set_fs(oldfs);
filp_close(fp_mac, NULL);
}
/* check .mac.info file is 0 byte */
- fp_mac = filp_open(filepath_old, O_RDONLY, 0);
+ fp_mac = filp_open(filepath_data, O_RDONLY, 0);
ret = kernel_read(fp_mac, 0, buf, 18);
if ((ret == 0) && (retry_count++ < 3)) {
@@ -793,10 +815,10 @@ startwrite:
/* end of /data/.mac.info */
/* File will be created /efs/wifi/.mac.info. */
- fp_mac = filp_open(filepath, O_RDWR | O_CREAT, 0666);
+ fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
if (IS_ERR(fp_mac)) {
- DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs));
return -1;
} else {
oldfs = get_fs();
@@ -807,17 +829,17 @@ startwrite:
sizeof(buf), &fp_mac->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI] Mac address [%s] Failed to"
- " write into File: %s\n", buf, filepath));
+ " write into File: %s\n", buf, filepath_efs));
else
DHD_INFO(("[WIFI] Mac address [%s] written"
- " into File: %s\n", buf, filepath));
+ " into File: %s\n", buf, filepath_efs));
}
set_fs(oldfs);
filp_close(fp_mac, NULL);
}
/* check .mac.info file is 0 byte */
- fp_mac = filp_open(filepath, O_RDONLY, 0);
+ fp_mac = filp_open(filepath_efs, O_RDONLY, 0);
ret = kernel_read(fp_mac, 0, buf, 18);
if ((ret == 0) && (retry_count++ < 3)) {
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c
index d01b9fc..ca43dda 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c
@@ -244,6 +244,10 @@ static uint32 maxdelay = 0, tspktcnt = 0, maxdelaypktno = 0;
#endif /* WLMEDIA_HTSF */
+#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
+/*SLP_wakelock_alternative_code*/
+extern struct device *pm_dev;
+#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */
#if defined(PKT_FILTER_SUPPORT)
#if defined(CUSTOMER_HW_SAMSUNG)
#define HEX_PREF_STR "0x"
@@ -617,13 +621,17 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
#ifdef BCM4334_CHIP
int bcn_li_bcn;
#endif
+#ifdef PASS_ALL_MCAST_PKTS
+ uint32 allmulti;
+#endif /* PASS_ALL_MCAST_PKTS */
DHD_ERROR(("%s: enter, value = %d in_suspend=%d\n",
__FUNCTION__, value, dhd->in_suspend));
if (dhd && dhd->up) {
if (value && dhd->in_suspend) {
-
+ if (wl_cfgp2p_p2p_listen_suspend())
+ DHD_ERROR(("failed to set WLC_E_P2P_PROBREQ_MSG\n"));
#ifdef PKT_FILTER_SUPPORT
dhd->early_suspended = 1;
#endif
@@ -637,7 +645,17 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
#endif
/* Enable packet filter, only allow unicast packet to send up */
- dhd_set_packet_filter(1, dhd);
+ if (dhd_pkt_filter_enable && !dhd->dhcp_in_progress) {
+ int i;
+ for (i = 0; i < dhd->pktfilter_count; i++)
+ dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
+ 1, dhd_master_mode);
+ }
+#ifdef PASS_ALL_MCAST_PKTS
+ allmulti = 0;
+ bcm_mkiovar("allmulti", (char *)&allmulti, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#endif /* PASS_ALL_MCAST_PKTS */
#ifndef CUSTOMER_HW_SAMSUNG
/* If DTIM skip is set up as default, force it to wake
@@ -676,7 +694,17 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
#endif
/* disable pkt filter */
- dhd_set_packet_filter(0, dhd);
+ if (dhd_pkt_filter_enable && !dhd->dhcp_in_progress) {
+ int i;
+ for (i = 0; i < dhd->pktfilter_count; i++)
+ dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
+ 0, dhd_master_mode);
+ }
+#ifdef PASS_ALL_MCAST_PKTS
+ allmulti = 1;
+ bcm_mkiovar("allmulti", (char *)&allmulti, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#endif /* PASS_ALL_MCAST_PKTS */
#ifndef CUSTOMER_HW_SAMSUNG
/* restore pre-suspend setting for dtim_skip */
@@ -1319,7 +1347,10 @@ _dhd_sysioc_thread(void *data)
}
if (dhd->set_macaddress == i+1) {
dhd->set_macaddress = 0;
- _dhd_set_mac_address(dhd, i, &dhd->macvalue);
+ if (0 == _dhd_set_mac_address(dhd, i, &dhd->macvalue))
+ DHD_INFO(("dhd_sysioc_thread: MACID is overwritten\n"));
+ else
+ DHD_ERROR(("dhd_sysioc_thread: _dhd_set_mac_address() failed\n"));
}
}
}
@@ -2334,16 +2365,6 @@ static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error)
{
if (!dhdp)
return FALSE;
-#ifdef BCM4334_CHIP
- if ((error == -ETIMEDOUT) || (error == -EREMOTEIO) || (dhdp->tx_seq_badcnt >= 2)
- || ((dhdp->busstate == DHD_BUS_DOWN)&&(!dhdp->dongle_reset))) {
- DHD_ERROR(("%s: Event HANG send up due to re=%d te=%d e=%d s=%d tse=%d\n",
- __FUNCTION__, dhdp->rxcnt_timeout, dhdp->txcnt_timeout, error,
- dhdp->busstate, dhdp->tx_seq_badcnt));
- net_os_send_hang_message(net);
- return TRUE;
- }
-#else
if ((error == -ETIMEDOUT) || (error == -EREMOTEIO)
|| ((dhdp->busstate == DHD_BUS_DOWN)&&(!dhdp->dongle_reset))) {
DHD_ERROR(("%s: Event HANG send up due to re=%d te=%d e=%d s=%d\n", __FUNCTION__,
@@ -2351,7 +2372,6 @@ static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error)
net_os_send_hang_message(net);
return TRUE;
}
-#endif
return FALSE;
}
@@ -2680,9 +2700,6 @@ dhd_stop(struct net_device *net)
dhd->pub.hang_was_sent = 0;
dhd->pub.rxcnt_timeout = 0;
dhd->pub.txcnt_timeout = 0;
-#ifdef BCM4334_CHIP
- dhd->pub.tx_seq_badcnt = 0;
-#endif
OLD_MOD_DEC_USE_COUNT;
exit:
DHD_OS_WAKE_UNLOCK(&dhd->pub);
@@ -3457,6 +3474,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
#ifdef AUTOCOUNTRY
int autocountry = 1;
#endif
+#ifdef VSDB
+ int interference_mode = 3;
+#endif
#ifdef PROP_TXSTATUS
dhd->wlfc_enabled = FALSE;
/* enable WLFC only if the firmware is VSDB */
@@ -3736,7 +3756,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
setbit(eventmask, WLC_E_ACTION_FRAME_RX);
setbit(eventmask, WLC_E_ACTION_FRAME_COMPLETE);
setbit(eventmask, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE);
- setbit(eventmask, WLC_E_P2P_PROBREQ_MSG);
setbit(eventmask, WLC_E_P2P_DISC_LISTEN_COMPLETE);
}
#endif /* WL_CFG80211 */
@@ -3812,6 +3831,12 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
}
}
#endif /* defined(SOFTAP) */
+ if (dhd->pktfilter_count) {
+ int i;
+
+ for (i = 0; i < dhd->pktfilter_count; i++)
+ dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]);
+ }
#endif /* PKT_FILTER_SUPPORT */
#ifdef VLAN_MODE_OFF
@@ -3828,6 +3853,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
DHD_ERROR(("%s Setting WL UP failed %d\n", __FUNCTION__, ret));
goto done;
}
+#ifdef VSDB
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_INTERFERENCE_MODE, (int *)&interference_mode, sizeof(int), TRUE, 0);
+#endif
#ifdef BCM4334_CHIP
bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn, 4, iovbuf, sizeof(iovbuf));
@@ -4598,6 +4626,9 @@ dhd_os_wd_timer(void *bus, uint wdtick)
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+ if (!dhd)
+ return;
+
flags = dhd_os_spin_lock(pub);
/* don't start the wd until fw is loaded */
@@ -4936,7 +4967,7 @@ void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar)
#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
struct dhd_info *dhdinfo = dhd->info;
dhd_os_sdunlock(dhd);
- wait_event_interruptible_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), HZ * 2);
+ wait_event_interruptible_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), HZ * 5);
dhd_os_sdlock(dhd);
#endif
return;
@@ -5034,6 +5065,7 @@ int net_os_rxfilter_add_remove(struct net_device *dev, int add_remove, int num)
}
}
dhd->pub.pktfilter[num] = filterp;
+ dhd_pktfilter_offload_set(&dhd->pub, dhd->pub.pktfilter[num]);
return ret;
#else
return 0;
@@ -5052,8 +5084,12 @@ int net_os_set_packet_filter(struct net_device *dev, int val)
*/
if (dhd && dhd->pub.up) {
if (dhd->pub.in_suspend) {
- if (!val || (val && !dhd->pub.suspend_disable_flag))
- dhd_set_packet_filter(val, &dhd->pub);
+ if (!val || (val && !dhd->pub.suspend_disable_flag)) {
+ int i;
+ for (i = 0; i < dhd->pub.pktfilter_count; i++)
+ dhd_pktfilter_offload_enable(&dhd->pub, dhd->pub.pktfilter[i],
+ val, dhd_master_mode);
+ }
}
}
return ret;
@@ -5337,6 +5373,9 @@ int dhd_os_wake_lock(dhd_pub_t *pub)
#ifdef CONFIG_HAS_WAKELOCK
if (!dhd->wakelock_counter)
wake_lock(&dhd->wl_wifi);
+#elif defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
+ /*SLP_wakelock_alternative_code*/
+ pm_stay_awake(pm_dev);
#endif
dhd->wakelock_counter++;
ret = dhd->wakelock_counter;
@@ -5369,6 +5408,9 @@ int dhd_os_wake_unlock(dhd_pub_t *pub)
#ifdef CONFIG_HAS_WAKELOCK
if (!dhd->wakelock_counter)
wake_unlock(&dhd->wl_wifi);
+#elif defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
+ /*SLP_wakelock_alternative_code*/
+ pm_relax(pm_dev);
#endif
ret = dhd->wakelock_counter;
}
@@ -5389,6 +5431,19 @@ int dhd_os_check_wakelock(void *dhdp)
if (dhd && wake_lock_active(&dhd->wl_wifi))
return 1;
+#elif defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
+ /*SLP_wakelock_alternative_code*/
+ dhd_pub_t *pub = (dhd_pub_t *)dhdp;
+ dhd_info_t *dhd;
+
+ if (!pub)
+ return 0;
+ dhd = (dhd_info_t *)(pub->info);
+
+ DHD_ERROR(("%s : wakelock_count = %d\n", __func__, dhd->wakelock_counter ));
+
+ if (dhd && (dhd->wakelock_counter > 0))
+ return 1;
#endif
return 0;
}
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c
index 2c411f8..052eaaf 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c
@@ -265,9 +265,6 @@ typedef struct dhd_bus {
bool activity; /* Activity flag for clock down */
int32 idletime; /* Control for activity timeout */
int32 idlecount; /* Activity timeout counter */
-#ifdef DHD_USE_IDLECOUNT
- int32 dhd_idlecount; /* DHD idle count */
-#endif /* DHD_USE_IDLECOUNT */
int32 idleclock; /* How to set bus driver when idle */
int32 sd_divisor; /* Speed control to bus driver */
int32 sd_mode; /* Mode control to bus driver */
@@ -1034,7 +1031,7 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok)
bus->activity = TRUE;
#ifdef DHD_USE_IDLECOUNT
- bus->dhd_idlecount = 0;
+ bus->idlecount = 0;
#endif /* DHD_USE_IDLECOUNT */
} else {
clkreq = 0;
@@ -1162,7 +1159,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
bus->activity = TRUE;
#ifdef DHD_USE_IDLECOUNT
- bus->dhd_idlecount = 0;
+ bus->idlecount = 0;
#endif /* DHD_USE_IDLECOUNT */
}
return ret;
@@ -1179,7 +1176,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
bus->activity = TRUE;
#ifdef DHD_USE_IDLECOUNT
- bus->dhd_idlecount = 0;
+ bus->idlecount = 0;
#endif /* DHD_USE_IDLECOUNT */
}
break;
@@ -1828,8 +1825,13 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen)
/* Send from dpc */
bus->ctrl_frame_buf = frame;
bus->ctrl_frame_len = len;
-
- dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat);
+ if(!bus->dpc_sched) {
+ bus->dpc_sched = TRUE;
+ dhd_sched_dpc(bus->dhd);
+ }
+ if (bus->ctrl_frame_stat) {
+ dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat);
+ }
if (bus->ctrl_frame_stat == FALSE) {
DHD_INFO(("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__));
@@ -4645,22 +4647,11 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
}
/* Check window for sanity */
-#ifdef BCM4334_CHIP
- if ((uint8)(txmax - bus->tx_seq) > 0x40) {
- DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n",
- __FUNCTION__, txmax, bus->tx_seq));
- txmax = bus->tx_max;
- bus->dhd->tx_seq_badcnt++;
- }
- else
- bus->dhd->tx_seq_badcnt = 0;
-#else
if ((uint8)(txmax - bus->tx_seq) > 0x40) {
DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n",
__FUNCTION__, txmax, bus->tx_seq));
txmax = bus->tx_max;
}
-#endif
bus->tx_max = txmax;
#ifdef DHD_DEBUG
@@ -4813,22 +4804,11 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
}
/* Check window for sanity */
-#ifdef BCM4334_CHIP
- if ((uint8)(txmax - bus->tx_seq) > 0x40) {
- DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n",
- __FUNCTION__, txmax, bus->tx_seq));
- txmax = bus->tx_max;
- bus->dhd->tx_seq_badcnt++;
- }
- else
- bus->dhd->tx_seq_badcnt = 0;
-#else
if ((uint8)(txmax - bus->tx_seq) > 0x40) {
DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n",
__FUNCTION__, txmax, bus->tx_seq));
txmax = bus->tx_max;
}
-#endif
bus->tx_max = txmax;
/* Call a separate function for control frames */
@@ -5296,6 +5276,13 @@ clkwait:
if (TXCTLOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) {
int ret, i;
+ uint8* frame_seq = bus->ctrl_frame_buf + SDPCM_FRAMETAG_LEN;
+ if (*frame_seq != bus->tx_seq) {
+ DHD_INFO(("%s IOCTL frame seq lag detected!"
+ " frm_seq:%d != bus->tx_seq:%d, corrected\n",
+ __FUNCTION__, *frame_seq, bus->tx_seq));
+ *frame_seq = bus->tx_seq;
+ }
ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
(uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len,
@@ -5720,9 +5707,6 @@ dhd_disable_intr(dhd_pub_t *dhdp)
bcmsdh_intr_disable(bus->sdh);
}
-#ifdef DHD_USE_IDLECOUNT
-#define DHD_IDLE_TIMEOUT_MS (50)
-#endif /* DHD_USE_IDLECOUNT */
extern bool
dhd_bus_watchdog(dhd_pub_t *dhdp)
@@ -5805,31 +5789,27 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
#endif
/* On idle timeout clear activity flag and/or turn off clock */
- if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
#ifdef DHD_USE_IDLECOUNT
- if (++bus->idlecount >= bus->idletime) {
- bus->idlecount = 0;
if (bus->activity)
bus->activity = FALSE;
else {
- bus->dhd_idlecount++;
+ bus->idlecount++;
- if (bus->dhd_idlecount >= (DHD_IDLE_TIMEOUT_MS/dhd_watchdog_ms)) {
+ if (bus->idlecount >= bus->idletime) {
DHD_TIMER(("%s: DHD Idle state!!\n", __FUNCTION__));
if (SLPAUTO_ENAB(bus)) {
if (dhdsdio_bussleep(bus, TRUE) != BCME_BUSY)
dhd_os_wd_timer(bus->dhd, 0);
- }
- else
+ } else
dhdsdio_clkctl(bus, CLK_NONE, FALSE);
- bus->dhd_idlecount = 0;
+ bus->idlecount = 0;
}
}
- }
#else
+ if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
if (++bus->idlecount >= bus->idletime) {
bus->idlecount = 0;
if (bus->activity) {
@@ -5840,8 +5820,8 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
dhdsdio_clkctl(bus, CLK_NONE, FALSE);
}
}
-#endif /* DHD_USE_IDLECOUNT */
}
+#endif /* DHD_USE_IDLECOUNT */
return bus->ipend;
}
@@ -6147,6 +6127,12 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
goto fail;
}
+#ifdef BCMHOST_XTAL_PU_TIME_MOD
+#ifdef BCM4334_CHIP
+ bcmsdh_reg_write(bus->sdh, 0x18000620, 2, 11);
+ bcmsdh_reg_write(bus->sdh, 0x18000628, 4, 0x00A60001);
+#endif
+#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
mutex_unlock(&_dhd_sdio_mutex_lock_);
DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__));
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h
index 89fc7ee..2d1d200 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h
@@ -40,7 +40,8 @@
#define HW_OOB
#endif
-#ifdef CONFIG_MACH_U1 /* Q1 also uses this feature */
+/* Q1 also uses this feature */
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS)
#ifdef CONFIG_MACH_Q1_BD
#define HW_OOB
#endif
@@ -48,6 +49,11 @@
#define WRITE_MACADDR
#endif
+#ifdef CONFIG_MACH_GC1
+#undef USE_CID_CHECK
+#define READ_MACADDR
+#endif
+
/* REGION CODE */
#if (WLAN_REGION_CODE >= 100) && (WLAN_REGION_CODE < 200) /*EUR*/
@@ -106,3 +112,6 @@
#define BCMWAPI_WAI
#endif
+#if !defined(READ_MACADDR) && !defined(WRITE_MACADDR) && !defined(RDWR_KORICS_MACADDR) && !defined(RDWR_MACADDR)
+#define GET_MAC_FROM_OTP
+#endif
diff --git a/drivers/net/wireless/bcmdhd/src/include/epivers.h b/drivers/net/wireless/bcmdhd/src/include/epivers.h
index 058f1d4..8be59f6 100644
--- a/drivers/net/wireless/bcmdhd/src/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/src/include/epivers.h
@@ -30,19 +30,19 @@
#define EPI_MINOR_VERSION 15
-#define EPI_RC_NUMBER 11
+#define EPI_RC_NUMBER 12
#define EPI_INCREMENTAL_NUMBER 0
#define EPI_BUILD_NUMBER 0
-#define EPI_VERSION 1, 15, 11, 0
+#define EPI_VERSION 1, 15, 12, 0
#define EPI_VERSION_NUM 0x010f0900
-#define EPI_VERSION_DEV 1.15.11
+#define EPI_VERSION_DEV 1.15.12
-#define EPI_VERSION_STR "1.15.11"
+#define EPI_VERSION_STR "1.15.12"
#endif /* _epivers_h_ */
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c
index 1704701..49782c5 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c
@@ -132,7 +132,10 @@ typedef struct cmd_tlv {
#ifdef BCM4334_CHIP //ampdu_mpdu
#define CMD_AMPDU_MPDU "AMPDU_MPDU"
#endif
-
+#ifdef VSDB
+#define CMD_CHANGE_RL "CHANGE_RL"
+#define CMD_RESTORE_RL "RESTORE_RL"
+#endif
typedef struct android_wifi_priv_cmd {
char *buf;
int used_len;
@@ -778,10 +781,12 @@ wl_android_set_auto_channel(struct net_device *dev, const char* string_num,
}
done:
- snprintf(command, total_len, "%d", channel);
+// snprintf(command, total_len, "%d", channel);
+ snprintf(command, 4, "%d", channel);
DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command));
- return 1;
+// return 1;
+ return 4;
}
static int
@@ -895,6 +900,31 @@ wl_android_okc_enable(struct net_device *dev, char *command, int total_len)
}
#endif /* OKC_ SUPPORT */
+#ifdef VSDB
+static int
+wl_android_ch_res_rl(struct net_device *dev, bool change)
+{
+ int error = 0;
+ s32 srl = 7;
+ s32 lrl = 4;
+ printk("%s enter\n", __FUNCTION__);
+ if (change) {
+ srl = 4;
+ lrl = 2;
+ }
+ error = wldev_ioctl(dev, WLC_SET_SRL, &srl,
+ sizeof(s32), true);
+ if (error) {
+ DHD_ERROR(("Failed to set SRL, error = %d\n", error));
+ }
+ error = wldev_ioctl(dev, WLC_SET_LRL, &lrl,
+ sizeof(s32), true);
+ if (error) {
+ DHD_ERROR(("Failed to set LRL, error = %d\n", error));
+ }
+ return error;
+}
+#endif
#ifdef BCM4334_CHIP //ampdu_mpdu
static int
@@ -1012,8 +1042,9 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
/* TBD: BTCOEXSCAN-STOP */
}
else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) {
+#if !defined(CUSTOMER_HW_SAMSUNG)
uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0';
-#if 0
+
if (mode == 1)
net_os_set_packet_filter(net, 0); /* DHCP starts */
else
@@ -1116,7 +1147,9 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
else if (strnicmp(command, CMD_SET_HAPD_AUTO_CHANNEL,
strlen(CMD_SET_HAPD_AUTO_CHANNEL)) == 0) {
int skip = strlen(CMD_SET_HAPD_AUTO_CHANNEL) + 3;
- wl_android_set_auto_channel(net, (const char*)command+skip, command,
+// wl_android_set_auto_channel(net, (const char*)command+skip, command,
+// priv_cmd.total_len);
+ bytes_written = wl_android_set_auto_channel(net, (const char*)command+skip, command,
priv_cmd.total_len);
}
else if (strnicmp(command, CMD_SET_HAPD_MAX_NUM_STA,
@@ -1162,6 +1195,12 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
bytes_written = wl_android_set_ampdu_mpdu(net, (const char*)command+skip);
}
#endif
+#ifdef VSDB
+ else if (strnicmp(command, CMD_CHANGE_RL, strlen(CMD_CHANGE_RL)) == 0)
+ bytes_written = wl_android_ch_res_rl(net, true);
+ else if (strnicmp(command, CMD_RESTORE_RL, strlen(CMD_RESTORE_RL)) == 0)
+ bytes_written = wl_android_ch_res_rl(net, false);
+#endif
else {
if ((strnicmp(command, CMD_START, strlen(CMD_START)) != 0) &&
(strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) != 0))
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c
index f805d60..c74adcc 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c
@@ -402,7 +402,6 @@ static __used bool wl_is_ibssstarter(struct wl_priv *wl);
*/
static s32 __wl_cfg80211_up(struct wl_priv *wl);
static s32 __wl_cfg80211_down(struct wl_priv *wl);
-static s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add);
static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev);
static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
@@ -2462,9 +2461,9 @@ wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
val = WL_AUTH_OPEN_SHARED;
WL_DBG(("automatic\n"));
break;
+#ifdef BCMCCX
case NL80211_AUTHTYPE_NETWORK_EAP:
WL_DBG(("network eap\n"));
-#ifdef BCMCCX
val = DOT11_LEAP_AUTH;
break;
#endif
@@ -4286,6 +4285,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
#ifdef WL_CFG80211_SYNC_GON_TIME
bool is_waiting_more_time = false;
#endif /* WL_CFG80211_SYNC_GON_TIME */
+ bool is_PROVDIS_REQ_GO = false;
WL_DBG(("Enter \n"));
@@ -4542,8 +4542,14 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
memcpy(wl->afx_hdl->tx_dst_addr.octet,
af_params->action_frame.da.octet,
sizeof(wl->afx_hdl->tx_dst_addr.octet));
+ if ((act_frm->subtype == P2P_PAF_PROVDIS_REQ) &&
+ (p2p_ie = wl_cfgp2p_find_p2pie((u8 *)act_frm->elts, action_frame->len)) != NULL) {
+ if ((ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID))) {
+ is_PROVDIS_REQ_GO = true;
+ }
+ }
- if (IS_P2P_SOCIAL(af_params->channel) &&
+ if (!is_PROVDIS_REQ_GO && IS_P2P_SOCIAL(af_params->channel) &&
(IS_P2P_PUB_ACT_REQ(act_frm, action_frame->len) ||
IS_GAS_REQ(sd_act_frm, action_frame->len)) &&
wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) {
@@ -5132,6 +5138,14 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
is_bssup = wl_cfgp2p_bss_isup(dev, bssidx);
if (!is_bssup && (wpa2_ie != NULL)) {
+ if (!info->dtim_period) {
+ info->dtim_period = 1;
+ }
+ if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD,
+ &info->dtim_period, sizeof(s32), true)) < 0) {
+ WL_ERR(("DTIM Interval Set Error, %d\n", err));
+ return err;
+ }
wldev_iovar_setint(dev, "mpc", 0);
if ((err = wl_validate_wpa2ie(dev, wpa2_ie, bssidx)) < 0) {
WL_ERR(("WPA2 IE parsing error"));
@@ -5248,13 +5262,15 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
return err;
}
}
- if (info->dtim_period) {
- if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD,
- &info->dtim_period, sizeof(s32), true)) < 0) {
- WL_ERR(("DTIM Interval Set Error, %d\n", err));
- return err;
- }
+ if (!info->dtim_period) {
+ info->dtim_period = 1;
}
+ if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD,
+ &info->dtim_period, sizeof(s32), true)) < 0) {
+ WL_ERR(("DTIM Interval Set Error, %d\n", err));
+ return err;
+ }
+
err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true);
if (unlikely(err)) {
WL_ERR(("WLC_UP error (%d)\n", err));
@@ -5734,20 +5750,26 @@ wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE
- body=kzalloc(len, GFP_KERNEL);
WL_DBG(("Enter \n"));
+ if (!len && (event == WLC_E_DEAUTH)) {
+ len = 2; /* reason code field */
+ data = &reason;
+ }
+ if (len) {
+ body=kzalloc(len, GFP_KERNEL);
+
if(body==NULL) {
WL_ERR(("wl_notify_connect_status: Failed to allocate body\n"));
return WL_INVALID;
}
-
+ }
memset(&bssid, 0, ETHER_ADDR_LEN);
WL_DBG(("Enter \n"));
if (wl_get_mode_by_netdev(wl, ndev) == WL_INVALID) {
kfree(body);
return WL_INVALID;
}
-
+ if (len)
memcpy(body, data, len);
wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
@@ -5858,8 +5880,6 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
if (wl_is_linkup(wl, e, ndev)) {
wl_link_up(wl);
act = true;
- wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
- wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
if (wl_is_ibssmode(wl, ndev)) {
printk("cfg80211_ibss_joined\n");
cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
@@ -5874,6 +5894,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
wl_read_prof(wl, ndev, WL_PROF_SSID))->SSID));
}
}
+ wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
+ wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
} else if (wl_is_linkdown(wl, e)) {
if (wl->scan_request) {
@@ -6222,18 +6244,17 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
WL_DBG((" Enter\n"));
#ifdef ESCAN_RESULT_PATCH
- if (memcmp(curbssid, broad_bssid, ETHER_ADDR_LEN) == 0 &&
- memcmp(broad_bssid, connect_req_bssid, ETHER_ADDR_LEN) != 0) {
- WL_DBG(("copy bssid\n"));
- memcpy(curbssid, connect_req_bssid, ETHER_ADDR_LEN);
- }
if (wl_get_drv_status(wl, CONNECTED, ndev)) {
if (memcmp(curbssid, connect_req_bssid, ETHER_ADDR_LEN) == 0) {
WL_ERR((" Connected event of connected device, ignore it\n"));
return err;
}
}
-
+ if (memcmp(curbssid, broad_bssid, ETHER_ADDR_LEN) == 0 &&
+ memcmp(broad_bssid, connect_req_bssid, ETHER_ADDR_LEN) != 0) {
+ WL_DBG(("copy bssid\n"));
+ memcpy(curbssid, connect_req_bssid, ETHER_ADDR_LEN);
+ }
WL_SCAN2(("Connect done \n"));
#if defined(BCM4334_CHIP)
@@ -6403,7 +6424,8 @@ wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
bcopy((const char*)da, (u8*)&hdr->da, ETHER_ADDR_LEN);
bcopy((const char*)sa, (u8*)&hdr->sa, ETHER_ADDR_LEN);
bcopy((const char*)bssid, (u8*)&hdr->bssid, ETHER_ADDR_LEN);
- bcopy((const char*)pbody, offset, prebody_len);
+ if ((pbody != NULL) && prebody_len)
+ bcopy((const char*)pbody, offset, prebody_len);
*body_len = totlen;
return err;
}
@@ -7103,7 +7125,8 @@ wl_cfg80211_netdev_notifier_call(struct notifier_block * nb,
return NOTIFY_DONE;
switch (state) {
case NETDEV_DOWN:
- while(work_pending(&wdev->cleanup_work)) {
+ while(work_pending(&wdev->cleanup_work) && refcnt < 100) {
+ if(refcnt%5==0)
WL_ERR(("%s : [NETDEV_DOWN] work_pending (%d th)\n",
__FUNCTION__, refcnt));
set_current_state(TASK_INTERRUPTIBLE);
@@ -7265,10 +7288,6 @@ static s32 wl_escan_handler(struct wl_priv *wl,
} else {
int cur_len = 0;
list = (wl_scan_results_t *)wl->escan_info.escan_buf[wl->escan_info.cur_sync_id%2];
- if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
- WL_ERR(("Buffer is too small: ignoring\n"));
- goto exit;
- }
#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
for (i = 0; i < list->count; i++) {
bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length))
@@ -7276,25 +7295,26 @@ static s32 wl_escan_handler(struct wl_priv *wl,
if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) &&
CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) &&
bi->SSID_len == bss->SSID_len &&
- !bcmp(bi->SSID, bss->SSID, bi->SSID_len)
- && (bi->length == bss->length)) {
- if (p2p_is_on(wl) && p2p_scan(wl)) {
- if (bss->dtoh32(ie_length)< bi_length) {
- int prev_len = dtoh32(bss->length);
- WL_SCAN2(("bss info replacement is occured(bcast:%d->probresp%d)\n",
- bss->ie_length, bi->ie_length));
- /* prev : broadcast, cur : prob_resp */
- if (list->count != 1 && i < list->count -1) {
- /* memory copy required by this case only */
- memcpy((u8 *)bss,
- (u8 *)bss + prev_len, list->buflen - cur_len - prev_len);
- }
- list->buflen -= prev_len;
- memcpy(&(((u8 *)list)[list->buflen]), bi, bi_length);
- list->version = dtoh32(bi->version);
- list->buflen += bi_length;
+ !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) {
+ if (bss->dtoh32(ie_length) != bi_length) {
+ int prev_len = dtoh32(bss->length);
+ WL_SCAN2(("bss info replacement is occured(bcast:%d->probresp%d)\n",
+ bss->ie_length, bi->ie_length));
+ /* prev : broadcast, cur : prob_resp */
+ if (list->count != 1 && i < list->count -1) {
+ /* memory copy required by this case only */
+ memcpy((u8 *)bss,
+ (u8 *)bss + prev_len, list->buflen - cur_len - prev_len);
+ }
+ list->buflen -= prev_len;
+ if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
+ WL_ERR(("Buffer is too small: ignoring\n"));
goto exit;
}
+ memcpy(&(((u8 *)list)[list->buflen]), bi, bi_length);
+ list->version = dtoh32(bi->version);
+ list->buflen += bi_length;
+ goto exit;
}
if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
(bi->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
@@ -7315,6 +7335,10 @@ static s32 wl_escan_handler(struct wl_priv *wl,
}
cur_len += dtoh32(bss->length);
}
+ if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
+ WL_ERR(("Buffer is too small: ignoring\n"));
+ goto exit;
+ }
memcpy(&(wl->escan_info.escan_buf[wl->escan_info.cur_sync_id%2][list->buflen]), bi, bi_length);
list->version = dtoh32(bi->version);
list->buflen += bi_length;
@@ -7373,6 +7397,12 @@ static s32 wl_escan_handler(struct wl_priv *wl,
}
wl->escan_info.cur_sync_id += 2;
}
+ else if (status == WLC_E_STATUS_NEWSCAN)
+ {
+ escan_result = (wl_escan_result_t *) data;
+ WL_ERR(("WLC_E_STATUS_NEWSCAN : scan_request[%p]\n", wl->scan_request));
+ WL_ERR(("sync_id[%d], bss_count[%d]\n", escan_result->sync_id, escan_result->bss_count));
+ }
else {
WL_ERR(("unexpected Escan Event %d : abort\n", status));
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
@@ -7405,12 +7435,17 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in
{
s32 pm = PM_FAST;
s32 err = BCME_OK;
+ s32 glom = -1;
+ u32 chan = 0;
+ u32 chanspec = 0;
+ u32 prev_chan = 0;
+ u32 connected_cnt = 0;
struct net_info *iter, *next;
+ struct net_device *primary_dev = wl_to_prmry_ndev(wl);
if (set) { /* set */
switch (state) {
case WL_STATUS_CONNECTED: {
- if (wl_get_drv_status_all(wl, CONNECTED) > 1) {
- wl->vsdb_mode = true;
+ if ((connected_cnt = wl_get_drv_status_all(wl, CONNECTED)) > 1) {
pm = PM_OFF;
WL_INFO(("Do not enable the power save for VSDB mode\n"));
} else if (_net_info->pm_block) {
@@ -7419,10 +7454,22 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in
pm = PM_FAST;
}
for_each_ndev(wl, iter, next) {
- if (!wl->vsdb_mode && (iter->ndev != _net_info->ndev))
+ if ((connected_cnt == 1) && (iter->ndev != _net_info->ndev))
continue;
- if (wl_get_drv_status(wl, CONNECTED, iter->ndev) &&
- (wl_get_mode_by_netdev(wl, iter->ndev) == WL_MODE_BSS)) {
+ chanspec = 0;
+ chan = 0;
+ if (wl_get_drv_status(wl, CONNECTED, iter->ndev)) {
+ if (wldev_iovar_getint(iter->ndev, "chanspec", (s32 *)&chanspec) == BCME_OK) {
+ chan = CHSPEC_CHANNEL(chanspec);
+ if (CHSPEC_IS40(chanspec)) {
+ if (CHSPEC_SB_UPPER(chanspec))
+ chan += CH_10MHZ_APART;
+ else
+ chan -= CH_10MHZ_APART;
+ }
+ wl_update_prof(wl, iter->ndev, NULL, &chan, WL_PROF_CHAN);
+ }
+ if ((wl_get_mode_by_netdev(wl, iter->ndev) == WL_MODE_BSS)) {
pm = htod32(pm);
WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm, sizeof(pm), true);
@@ -7434,6 +7481,23 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in
break;
}
}
+ if (connected_cnt > 1) {
+ if (!prev_chan && chan)
+ prev_chan = chan;
+ else if (prev_chan && (prev_chan != chan)){
+ wl->vsdb_mode = true;
+ }
+ }
+ }
+ }
+ if ((wl_get_mode_by_netdev(wl, _net_info->ndev) == WL_MODE_AP) && p2p_is_on(wl))
+ if (wl_add_remove_eventmsg(primary_dev, WLC_E_P2P_PROBREQ_MSG, true) != BCME_OK)
+ CFGP2P_ERR((" failed to set WLC_E_P2P_PROPREQ_MSG\n"));
+ if (!wl->vsdb_mode && (connected_cnt > 1)) {
+ if (wldev_iovar_getint(primary_dev, "bus:txglom", (s32 *)&glom) == BCME_OK) {
+ wl->glom = glom;
+ wldev_iovar_setint(primary_dev, "bus:txglom", 0);
+ }
}
break;
}
@@ -7443,6 +7507,8 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in
} else { /* clear */
switch (state) {
case WL_STATUS_CONNECTED: {
+ chan = 0;
+ wl_update_prof(wl, _net_info->ndev, NULL, &chan, WL_PROF_CHAN);
if (wl_get_drv_status_all(wl, CONNECTED) == 1) {
wl->vsdb_mode = false;
for_each_ndev(wl, iter, next) {
@@ -7465,7 +7531,13 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in
}
}
}
+ if (wl->glom != -1)
+ wldev_iovar_setint(primary_dev, "bus:txglom", wl->glom);
+ wl->glom = -1;
}
+ if ((wl_get_mode_by_netdev(wl, _net_info->ndev) == WL_MODE_AP) && p2p_is_on(wl))
+ if (wl_add_remove_eventmsg(primary_dev, WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK)
+ CFGP2P_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n"));
break;
}
default:
@@ -7524,6 +7596,7 @@ static s32 wl_init_priv(struct wl_priv *wl)
wl->rf_blocked = false;
wl->first_remain = true;
wl->wlfc_on = false;
+ wl->glom = -1;
set_bit(WL_STATUS_CONNECTED, &wl->interrested_state);
spin_lock_init(&wl->cfgdrv_lock);
mutex_init(&wl->ioctl_buf_sync);
@@ -7997,7 +8070,7 @@ static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 ift
return 0;
}
-static s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
+s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
{
s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
@@ -8088,6 +8161,9 @@ static int wl_construct_reginfo(struct wl_priv *wl, s32 bw_cap)
n_cnt = &n_5g;
band = IEEE80211_BAND_5GHZ;
ht40_allowed = (bw_cap == WLC_N_BW_20ALL)? false : true;
+ } else {
+ WL_ERR(("Invalid channel Sepc. 0x%x.\n", c));
+ continue;
}
for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
if (band_chan_arr[j].hw_value == channel) {
@@ -8377,6 +8453,8 @@ static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item)
break;
case WL_PROF_SSID:
rptr = &profile->ssid;
+ case WL_PROF_CHAN:
+ rptr = &profile->channel;
break;
}
spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
@@ -8423,6 +8501,8 @@ wl_update_prof(struct wl_priv *wl, struct net_device *ndev,
case WL_PROF_DTIMPERIOD:
profile->dtim_period = *(u8 *)data;
break;
+ case WL_PROF_CHAN:
+ profile->channel = *(u32*)data;
default:
err = -EOPNOTSUPP;
break;
@@ -8607,17 +8687,44 @@ s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len,
{
struct wl_priv *wl;
struct net_device *ndev = NULL;
+ struct ether_addr primary_mac;
s32 ret = 0;
s32 bssidx = 0;
s32 pktflag = 0;
wl = wlcfg_drv_priv;
- if (wl->p2p && wl->p2p->vif_created) {
- ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
- bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION);
- } else if (wl_get_drv_status(wl, AP_CREATING, net) ||
+
+ if (wl_get_drv_status(wl, AP_CREATING, net) ||
wl_get_drv_status(wl, AP_CREATED, net)) {
ndev = net;
bssidx = 0;
+ } else if (wl->p2p) {
+ if (net == wl->p2p_net) {
+ net = wl_to_prmry_ndev(wl);
+ }
+ if (!wl->p2p->on) {
+ get_primary_mac(wl, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
+
+ /* In case of p2p_listen command, supplicant send remain_on_channel
+ * without turning on P2P
+ */
+
+ p2p_on(wl) = true;
+ ret = wl_cfgp2p_enable_discovery(wl, net, NULL, 0);
+
+ if (unlikely(ret)) {
+ goto exit;
+ }
+ }
+ if (net != wl_to_prmry_ndev(wl)) {
+ if (wl_get_mode_by_netdev(wl, net) == WL_MODE_AP) {
+ ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION);
+ }
+ } else {
+ ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
+ }
}
if (ndev != NULL) {
switch (type) {
@@ -8634,7 +8741,7 @@ s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len,
if (pktflag)
ret = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, pktflag, buf, len);
}
-
+exit:
return ret;
}
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h
index cc8e7e1..04bd49e 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h
@@ -65,7 +65,7 @@ struct wl_ibss;
#define WL_ERR(args) \
do { \
if (wl_dbg_level & WL_DBG_ERR) { \
- printk(KERN_ERR "CFG80211-INFO2) %s : ", __func__); \
+ printk(KERN_INFO "CFG80211-INFO2) %s : ", __func__); \
printk args; \
} \
} while (0)
@@ -75,7 +75,7 @@ do { \
#define WL_INFO(args) \
do { \
if (wl_dbg_level & WL_DBG_INFO) { \
- printk(KERN_ERR "CFG80211-INFO) %s : ", __func__); \
+ printk(KERN_INFO "CFG80211-INFO) %s : ", __func__); \
printk args; \
} \
} while (0)
@@ -85,7 +85,7 @@ do { \
#define WL_SCAN(args) \
do { \
if (wl_dbg_level & WL_DBG_SCAN) { \
- printk(KERN_ERR "CFG80211-SCAN) %s :", __func__); \
+ printk(KERN_INFO "CFG80211-SCAN) %s :", __func__); \
printk args; \
} \
} while (0)
@@ -95,7 +95,7 @@ do { \
#define WL_TRACE(args) \
do { \
if (wl_dbg_level & WL_DBG_TRACE) { \
- printk(KERN_ERR "CFG80211-TRACE) %s :", __func__); \
+ printk(KERN_INFO "CFG80211-TRACE) %s :", __func__); \
printk args; \
} \
} while (0)
@@ -103,7 +103,7 @@ do { \
#define WL_DBG(args) \
do { \
if (wl_dbg_level & WL_DBG_DBG) { \
- printk(KERN_ERR "CFG80211-DEBUG) %s :", __func__); \
+ printk(KERN_DEBUG "CFG80211-DEBUG) %s :", __func__); \
printk args; \
} \
} while (0)
@@ -116,7 +116,7 @@ do { \
#define WL_SCAN2(args) \
do { \
if (wl_dbg_level & WL_DBG_SCAN2) { \
- printk(KERN_ERR "CFG80211-SCAN) %s :", __func__); \
+ printk(KERN_DEBUG "CFG80211-SCAN) %s :", __func__); \
printk args; \
} \
} while (0)
@@ -193,6 +193,7 @@ enum wl_prof_list {
WL_PROF_SEC,
WL_PROF_IBSS,
WL_PROF_BAND,
+ WL_PROF_CHAN,
WL_PROF_BSSID,
WL_PROF_ACT,
WL_PROF_BEACONINT,
@@ -292,6 +293,7 @@ struct wl_ibss {
struct wl_profile {
u32 mode;
s32 band;
+ u32 channel;
struct wlc_ssid ssid;
struct wl_security sec;
struct wl_ibss ibss;
@@ -453,6 +455,7 @@ struct wl_priv {
void *pub;
u32 iface_cnt;
u32 channel; /* current channel */
+ s32 glom;
#ifdef WL_CFG80211_SYNC_GON_TIME
u32 af_sent_channel; /* channel action frame is sent */
/* save the next gon af subtype when it needs to wait more time for next gon af
@@ -796,4 +799,5 @@ extern s32 wl_update_wiphybands(struct wl_priv *wl);
extern s32 wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev);
extern s32 wl_cfg80211_if_is_group_owner(void);
+extern s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add);
#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c
index f25cae4..fdc2ed8 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c
@@ -41,20 +41,25 @@
#include <bcmutils.h>
#include <bcmendian.h>
#include <proto/ethernet.h>
-
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhdioctl.h>
+#include <wlioctl.h>
+#include <dhd_cfg80211.h>
#include <wl_cfg80211.h>
#include <wl_cfgp2p.h>
#include <wldev_common.h>
#include <wl_android.h>
static s8 scanparambuf[WLC_IOCTL_SMLEN];
-
+static s8 g_mgmt_ie_buf[2048];
+extern struct wl_priv *wlcfg_drv_priv;
static bool
wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type);
-static s32
-wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag,
- s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete);
+static u32
+wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 bssidx, s32 pktflag,
+ s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd);
static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev);
static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd);
@@ -924,13 +929,17 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
s32 ret = BCME_OK;
u32 pos;
u8 *ie_buf;
+ u8 *curr_ie_buf = NULL;
u8 *mgmt_ie_buf = NULL;
u32 mgmt_ie_buf_len = 0;
u32 *mgmt_ie_len = 0;
+ u32 del_add_ie_buf_len = 0;
+ u32 total_ie_buf_len = 0;
u8 ie_id, ie_len;
- u8 delete = 0;
#define IE_TYPE(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie)
#define IE_TYPE_LEN(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie_len)
+ memset(g_mgmt_ie_buf, 0, sizeof(g_mgmt_ie_buf));
+ curr_ie_buf = g_mgmt_ie_buf;
if (p2p_is_on(wl) && bssidx != -1) {
if (bssidx == P2PAPI_BSSCFG_PRIMARY)
bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
@@ -1020,7 +1029,6 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
goto exit;
}
pos = 0;
- delete = 1;
ie_buf = (u8 *) mgmt_ie_buf;
while (pos < *mgmt_ie_len) {
ie_id = ie_buf[pos++];
@@ -1030,12 +1038,14 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0) ||
wl_cfgp2p_is_wfd_ie(&ie_buf[pos-2], NULL, 0) ||
wl_cfgp2p_is_customer_ie(&ie_buf[pos-2], NULL, 0))) {
- CFGP2P_INFO(("DELELED ID : %d, Len : %d , OUI :"
+ CFGP2P_INFO(("DELETED ID : %d, Len : %d , OUI :"
"%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos],
ie_buf[pos+1], ie_buf[pos+2]));
- ret = wl_cfgp2p_vndr_ie(wl, ndev, bssidx, pktflag,
+ del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf, bssidx, pktflag,
ie_buf+pos, VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3,
- ie_len-3, delete);
+ ie_len-3, "del");
+ curr_ie_buf += del_add_ie_buf_len;
+ total_ie_buf_len += del_add_ie_buf_len;
}
pos += ie_len;
}
@@ -1049,7 +1059,6 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
*mgmt_ie_len = vndr_ie_len;
pos = 0;
ie_buf = (u8 *) vndr_ie;
- delete = 0;
while (pos < vndr_ie_len) {
ie_id = ie_buf[pos++];
ie_len = ie_buf[pos++];
@@ -1061,14 +1070,21 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
CFGP2P_INFO(("ADDED ID : %d, Len : %d , OUI :"
"%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos],
ie_buf[pos+1], ie_buf[pos+2]));
- ret = wl_cfgp2p_vndr_ie(wl, ndev, bssidx, pktflag,
+ del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf, bssidx, pktflag,
ie_buf+pos, VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3,
- ie_len-3, delete);
+ ie_len-3, "add");
+ curr_ie_buf += del_add_ie_buf_len;
+ total_ie_buf_len += del_add_ie_buf_len;
}
pos += ie_len;
}
}
-
+ if (total_ie_buf_len) {
+ ret = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", g_mgmt_ie_buf, total_ie_buf_len,
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ if (ret)
+ CFGP2P_ERR(("vndr ie set error : %d\n", ret));
+ }
}
#undef IE_TYPE
#undef IE_TYPE_LEN
@@ -1203,15 +1219,13 @@ wl_cfgp2p_find_wfdie(u8 *parse, u32 len)
}
return NULL;
}
-static s32
-wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag,
- s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete)
+static u32
+wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 bssidx, s32 pktflag,
+ s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd)
{
- s32 err = BCME_OK;
- s32 buf_len;
+ vndr_ie_setbuf_t hdr; /* aligned temporary vndr_ie buffer header */
s32 iecount;
-
- vndr_ie_setbuf_t *ie_setbuf;
+ u32 data_offset;
/* Validate the pktflag parameter */
if ((pktflag & ~(VNDR_IE_BEACON_FLAG | VNDR_IE_PRBRSP_FLAG |
@@ -1221,36 +1235,34 @@ wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 p
return -1;
}
- buf_len = sizeof(vndr_ie_setbuf_t) + data_len - 1;
- ie_setbuf = (vndr_ie_setbuf_t *) kzalloc(buf_len, GFP_KERNEL);
+ /* Copy the vndr_ie SET command ("add"/"del") to the buffer */
+ strncpy(hdr.cmd, add_del_cmd, VNDR_IE_CMD_LEN - 1);
+ hdr.cmd[VNDR_IE_CMD_LEN - 1] = '\0';
- CFGP2P_INFO((" ie_id : %02x, data length : %d\n", ie_id, data_len));
- if (!ie_setbuf) {
-
- CFGP2P_ERR(("Error allocating buffer for IE\n"));
- return -ENOMEM;
- }
- if (delete)
- strcpy(ie_setbuf->cmd, "del");
- else
- strcpy(ie_setbuf->cmd, "add");
/* Buffer contains only 1 IE */
iecount = htod32(1);
- memcpy((void *)&ie_setbuf->vndr_ie_buffer.iecount, &iecount, sizeof(int));
+ memcpy((void *)&hdr.vndr_ie_buffer.iecount, &iecount, sizeof(s32));
pktflag = htod32(pktflag);
- memcpy((void *)&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].pktflag,
- &pktflag, sizeof(uint32));
- ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = ie_id;
- ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len
- = (uchar)(data_len + VNDR_IE_MIN_LEN);
- memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui, oui, 3);
- memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data, data, data_len);
- err = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", ie_setbuf, buf_len,
- wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ memcpy((void *)&hdr.vndr_ie_buffer.vndr_ie_list[0].pktflag, &pktflag,
+ sizeof(u32));
+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = ie_id;
+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len =
+ (uint8) VNDR_IE_MIN_LEN + datalen;
+
+ /* Add the IE OUI to the buffer */
+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[0] = oui[0];
+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[1] = oui[1];
+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[2] = oui[2];
+
+ /* Copy the aligned temporary vndr_ie buffer header to the IE buffer */
+ memcpy(iebuf, &hdr, sizeof(hdr) - 1);
+
+ data_offset =
+ (u8*)&hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data[0] -
+ (u8*)&hdr;
+ memcpy(iebuf + data_offset, data, datalen);
+ return data_offset + datalen;
- CFGP2P_INFO(("vndr_ie iovar returns %d\n", err));
- kfree(ie_setbuf);
- return err;
}
/*
@@ -1284,6 +1296,33 @@ wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev)
exit:
return index;
}
+s32 wl_cfgp2p_p2p_listen_suspend(void)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ bool enable = true;
+ s32 ret = BCME_OK;
+ s32 bssidx = -1;
+ struct net_device *netdev = wl_to_prmry_ndev(wl);
+ CFGP2P_ERR(("enter\n"));
+ if (wl == NULL || wl->p2p == NULL || netdev == NULL)
+ goto exit;
+ if (wl_get_p2p_status(wl, DISCOVERY_ON) == 0)
+ goto exit;
+ if (!timer_pending(&wl->p2p->listen_timer))
+ goto exit;
+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
+ if (bssidx) {
+ if (wl_to_p2p_bss_saved_ie(wl, bssidx).p2p_probe_res_ie_len)
+ enable = false;
+
+ if ((ret = wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, enable)) != BCME_OK) {
+ CFGP2P_ERR((" failed to %s WLC_E_P2P_PROPREQ_MSG\n", enable? "set":"unset" ));
+ }
+
+ }
+exit:
+ return ret;
+}
/*
* Callback function for WLC_E_P2P_DISC_LISTEN_COMPLETE
*/
@@ -1292,7 +1331,7 @@ wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data)
{
s32 ret = BCME_OK;
-
+ struct net_device *netdev = wl_to_prmry_ndev(wl);
CFGP2P_DBG((" Enter\n"));
if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) {
wl_set_p2p_status(wl, LISTEN_EXPIRED);
@@ -1333,6 +1372,9 @@ wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id,
&wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL);
}
+ if (wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK) {
+ CFGP2P_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n"));
+ }
} else
wl_clr_p2p_status(wl, LISTEN_EXPIRED);
@@ -1374,6 +1416,10 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
s32 ret = BCME_OK;
struct timer_list *_timer;
s32 extra_delay;
+ struct net_device *netdev = wl_to_prmry_ndev(wl);
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+ bool enable = true;
+ s32 bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
CFGP2P_DBG((" Enter Listen Channel : %d, Duration : %d\n", channel, duration_ms));
if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) {
@@ -1392,9 +1438,15 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
else
wl_clr_p2p_status(wl, LISTEN_EXPIRED);
#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
-
- ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms,
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ if (wl_to_p2p_bss_saved_ie(wl, bssidx).p2p_probe_res_ie_len && dhd && dhd->in_suspend) {
+ /* Clear WLC_E_P2P_PROBREQ_MSG in case of early suspend and p2p ie != 0 */
+ enable = false;
+ }
+
+ if (wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, enable) != BCME_OK) {
+ CFGP2P_ERR((" failed to set WLC_E_P2P_PROPREQ_MSG\n"));
+ }
+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms, bssidx);
_timer = &wl->p2p->listen_timer;
/* We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle ,
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.h
index ebc1030..348aeca 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.h
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.h
@@ -123,21 +123,21 @@ enum wl_cfgp2p_status {
#define CFGP2P_ERR(args) \
do { \
if (wl_dbg_level & WL_DBG_ERR) { \
- printk(KERN_ERR "CFGP2P-INFO2) %s : ", __func__); \
+ printk(KERN_INFO "CFGP2P-INFO2) %s : ", __func__); \
printk args; \
} \
} while (0)
#define CFGP2P_INFO(args) \
do { \
if (wl_dbg_level & WL_DBG_INFO) { \
- printk(KERN_ERR "CFGP2P-INFO) %s : ", __func__); \
+ printk(KERN_INFO "CFGP2P-INFO) %s : ", __func__); \
printk args; \
} \
} while (0)
#define CFGP2P_DBG(args) \
do { \
if (wl_dbg_level & WL_DBG_DBG) { \
- printk(KERN_ERR "CFGP2P-DEBUG) %s :", __func__); \
+ printk(KERN_DEBUG "CFGP2P-DEBUG) %s :", __func__); \
printk args; \
} \
} while (0)
@@ -221,6 +221,8 @@ wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev);
extern s32
+wl_cfgp2p_p2p_listen_suspend(void);
+extern s32
wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data);
extern s32
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index 955cc1a..4bf32eb 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -648,6 +648,8 @@ static void max77686_rtc_enable_wtsr(struct max77686_rtc_info *info, bool enable
dev_info(info->dev, "%s: %s WTSR\n", __func__,
enable ? "enable" : "disable");
+ max77686_rtc_update(info, MAX77686_RTC_READ);
+
ret = max77686_update_reg(info->rtc, MAX77686_WTSR_SMPL_CNTL, val, mask);
if (ret < 0) {
dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n",
@@ -673,6 +675,8 @@ static void max77686_rtc_enable_smpl(struct max77686_rtc_info *info, bool enable
dev_info(info->dev, "%s: %s SMPL\n", __func__,
enable ? "enable" : "disable");
+ max77686_rtc_update(info, MAX77686_RTC_READ);
+
ret = max77686_update_reg(info->rtc, MAX77686_WTSR_SMPL_CNTL, val, mask);
if (ret < 0) {
dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n",
@@ -681,10 +685,6 @@ static void max77686_rtc_enable_smpl(struct max77686_rtc_info *info, bool enable
}
max77686_rtc_update(info, MAX77686_RTC_WRITE);
-
- val = 0;
- max77686_read_reg(info->rtc, MAX77686_WTSR_SMPL_CNTL, &val);
- pr_info("%s: WTSR_SMPL(0x%02x)\n", __func__, val);
}
#endif /* MAX77686_RTC_WTSR_SMPL */
@@ -715,6 +715,8 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
data_alm2[RTC_WEEKDAY]);
#endif
+ max77686_rtc_update(info, MAX77686_RTC_READ);
+
ret = max77686_read_reg(info->rtc, MAX77686_RTC_CONTROL, &buf);
if (ret < 0) {
dev_err(info->dev, "%s: fail to read control reg(%d)\n",
@@ -722,12 +724,15 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
return ret;
}
+ if (buf & (1 << MODEL24_SHIFT)) {
+ dev_info(info->dev, "%s: bypass init\n", __func__);
+ return ret;
+ }
+
/* Set RTC control register : Binary mode, 24hour mdoe */
data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
- info->rtc_24hr_mode = 1;
-
ret = max77686_bulk_write(info->rtc, MAX77686_RTC_CONTROLM, 2, data);
if (ret < 0) {
dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
@@ -737,6 +742,18 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
max77686_rtc_update(info, MAX77686_RTC_WRITE);
+ /* Mask control register */
+ max77686_rtc_update(info, MAX77686_RTC_READ);
+
+ ret = max77686_update_reg(info->rtc, MAX77686_RTC_CONTROLM, 0x0, 0x3);
+ if (ret < 0) {
+ dev_err(info->dev, "%s: fail to mask CONTROLM reg(%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ max77686_rtc_update(info, MAX77686_RTC_WRITE);
+
/* If it's first boot, reset rtc to 1/1/2012 00:00:00(SUN) */
if (buf == 0) {
dev_info(info->dev, "rtc init\n");
@@ -775,6 +792,7 @@ static int __devinit max77686_rtc_probe(struct platform_device *pdev)
#if defined(CONFIG_RTC_ALARM_BOOT)
info->irq2 = max77686->irq_base + MAX77686_RTCIRQ_RTCA2;
#endif
+ info->rtc_24hr_mode = 1;
platform_set_drvdata(pdev, info);
@@ -861,6 +879,8 @@ static void max77686_rtc_shutdown(struct platform_device *pdev)
for (i = 0; i < 3; i++) {
max77686_rtc_enable_wtsr(info, false);
+
+ max77686_rtc_update(info, MAX77686_RTC_READ);
max77686_read_reg(info->rtc, MAX77686_WTSR_SMPL_CNTL, &val);
pr_info("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val);
if (val & WTSR_EN_MASK)
diff --git a/drivers/sensor/lsm330dlc_gyro.c b/drivers/sensor/lsm330dlc_gyro.c
index 1c48308..631730a 100644
--- a/drivers/sensor/lsm330dlc_gyro.c
+++ b/drivers/sensor/lsm330dlc_gyro.c
@@ -93,8 +93,8 @@
#define MIN_ST 175
#define MAX_ST 875
#define FIFO_TEST_WTM 0x1F
-#define MIN_ZERO_RATE -1714
-#define MAX_ZERO_RATE 1714 /* 30*1000/17.5 */
+#define MIN_ZERO_RATE -3142
+#define MAX_ZERO_RATE 3142 /* 55*1000/17.5 */
/* max and min entry */
#define MAX_ENTRY 20
diff --git a/drivers/usb/gadget/f_mtp_samsung.c b/drivers/usb/gadget/f_mtp_samsung.c
index aa58024..7f0dec8 100644
--- a/drivers/usb/gadget/f_mtp_samsung.c
+++ b/drivers/usb/gadget/f_mtp_samsung.c
@@ -94,11 +94,12 @@
/*-------------------------------------------------------------------------*/
#define MTPG_BULK_BUFFER_SIZE 4096
-#define INT_MAX_PACKET_SIZE 10
+#define MTPG_INTR_BUFFER_SIZE 28
/* number of rx and tx requests to allocate */
#define MTPG_RX_REQ_MAX 4
#define MTPG_MTPG_TX_REQ_MAX 4
+#define MTPG_INTR_REQ_MAX 5
/* ID for Microsoft MTP OS String */
#define MTPG_OS_STRING_ID 0xEE
@@ -124,8 +125,10 @@ struct mtpg_dev {
struct list_head tx_idle;
struct list_head rx_idle;
struct list_head rx_done;
+ struct list_head intr_idle;
wait_queue_head_t read_wq;
wait_queue_head_t write_wq;
+ wait_queue_head_t intr_wq;
struct usb_request *read_req;
unsigned char *read_buf;
@@ -134,7 +137,6 @@ struct mtpg_dev {
struct usb_ep *bulk_in;
struct usb_ep *bulk_out;
struct usb_ep *int_in;
- struct usb_request *notify_req;
atomic_t read_excl;
atomic_t write_excl;
@@ -192,8 +194,8 @@ static struct usb_endpoint_descriptor int_fs_notify_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
- .bInterval = 0x04,
+ .wMaxPacketSize = __constant_cpu_to_le16(MTPG_INTR_BUFFER_SIZE),
+ .bInterval = 6,
};
static struct usb_descriptor_header *fs_mtpg_desc[] = {
@@ -228,8 +230,8 @@ static struct usb_endpoint_descriptor int_hs_notify_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
- .bInterval = INT_MAX_PACKET_SIZE + 4,
+ .wMaxPacketSize = __constant_cpu_to_le16(MTPG_INTR_BUFFER_SIZE),
+ .bInterval = 6,
};
static struct usb_descriptor_header *hs_mtpg_desc[] = {
@@ -434,6 +436,13 @@ static int mtp_send_signal(int value)
info.si_code = SI_QUEUE;
info.si_int = value;
rcu_read_lock();
+
+ if (!current->nsproxy) {
+ printk(KERN_DEBUG "process has gone\n");
+ rcu_read_unlock();
+ return -ENODEV;
+ }
+
t = pid_task(find_vpid(mtp_pid), PIDTYPE_PID);
if (t == NULL) {
printk(KERN_DEBUG "no such pid\n");
@@ -710,34 +719,37 @@ static ssize_t interrupt_write(struct file *fd,
int ret;
DEBUG_MTPB("[%s] \tline = [%d]\n", __func__, __LINE__);
- req = dev->notify_req;
+
+ if (count > MTPG_INTR_BUFFER_SIZE)
+ return -EINVAL;
+
+ ret = wait_event_interruptible_timeout(dev->intr_wq,
+ (req = mtpg_req_get(dev, &dev->intr_idle)),
+ msecs_to_jiffies(1000));
if (!req) {
printk(KERN_ERR "[%s]Alloc has failed\n", __func__);
return -ENOMEM;
}
- if (_lock(&dev->wintfd_excl)) {
- printk(KERN_ERR "write failed on interrupt endpoint\n");
- return -EBUSY;
- }
-
if (copy_from_user(req->buf, buf, count)) {
+ mtpg_req_put(dev, &dev->intr_idle, req);
printk(KERN_ERR "[%s]copy from user has failed\n", __func__);
return -EIO;
}
req->length = count;
- req->complete = interrupt_complete;
+ /*req->complete = interrupt_complete;*/
ret = usb_ep_queue(dev->int_in, req, GFP_ATOMIC);
- if (ret < 0) {
- printk(KERN_ERR "[%s]usb_ep_queue failed\n", __func__);
- return -EIO;
+ if (ret) {
+ printk(KERN_ERR "[%s:%d]\n", __func__, __LINE__);
+ mtpg_req_put(dev, &dev->intr_idle, req);
}
- _unlock(&dev->wintfd_excl);
+ DEBUG_MTPB("[%s] \tline = [%d] returning ret is %d\\n",
+ __func__, __LINE__, ret);
return ret;
}
@@ -797,7 +809,7 @@ static long mtpg_ioctl(struct file *fd, unsigned int code, unsigned long arg)
status = usb_ep_clear_halt(dev->bulk_out);
break;
case MTP_WRITE_INT_DATA:
- printk(KERN_INFO "[%s]\t%d MTP intrpt_Write\n",
+ printk(KERN_INFO "[%s]\t%d MTP intrpt_Write no slep\n",
__func__, __LINE__);
ret_value = interrupt_write(fd, (const char *)arg,
MTP_MAX_PACKET_LEN_FROM_APP);
@@ -1009,6 +1021,19 @@ static void mtpg_complete_out(struct usb_ep *ep, struct usb_request *req)
wake_up(&dev->read_wq);
}
+static void mtpg_complete_intr(struct usb_ep *ep, struct usb_request *req)
+{
+ struct mtpg_dev *dev = the_mtpg;
+ /*printk(KERN_INFO "[%s]\tline = [%d]\n", __func__, __LINE__);*/
+
+ if (req->status != 0)
+ dev->error = 1;
+
+ mtpg_req_put(dev, &dev->intr_idle, req);
+
+ wake_up(&dev->intr_wq);
+}
+
static void
mtpg_function_unbind(struct usb_configuration *c, struct usb_function *f)
{
@@ -1022,6 +1047,9 @@ mtpg_function_unbind(struct usb_configuration *c, struct usb_function *f)
while ((req = mtpg_req_get(dev, &dev->tx_idle)))
mtpg_request_free(req, dev->bulk_in);
+
+ while ((req = mtpg_req_get(dev, &dev->intr_idle)))
+ mtpg_request_free(req, dev->int_in);
}
static int
@@ -1075,12 +1103,13 @@ mtpg_function_bind(struct usb_configuration *c, struct usb_function *f)
mtpg->int_in = ep;
the_mtpg->int_in = ep;
- mtpg->notify_req = alloc_ep_req(ep,
- sizeof(struct usb_mtp_ctrlrequest) + 2,
- GFP_ATOMIC);
- if (!mtpg->notify_req)
- goto out;
-
+ for (i = 0; i < MTPG_INTR_REQ_MAX; i++) {
+ req = mtpg_request_new(mtpg->int_in, MTPG_INTR_BUFFER_SIZE);
+ if (!req)
+ goto out;
+ req->complete = mtpg_complete_intr;
+ mtpg_req_put(mtpg, &mtpg->intr_idle, req);
+ }
for (i = 0; i < MTPG_RX_REQ_MAX; i++) {
req = mtpg_request_new(mtpg->bulk_out, MTPG_BULK_BUFFER_SIZE);
if (!req)
@@ -1110,7 +1139,6 @@ mtpg_function_bind(struct usb_configuration *c, struct usb_function *f)
int_hs_notify_desc.bEndpointAddress =
int_fs_notify_desc.bEndpointAddress;
- f->hs_descriptors = hs_mtpg_desc;
}
mtpg->cdev = cdev;
@@ -1402,6 +1430,7 @@ static int mtp_setup(void)
}
spin_lock_init(&mtpg->lock);
+ init_waitqueue_head(&mtpg->intr_wq);
init_waitqueue_head(&mtpg->read_wq);
init_waitqueue_head(&mtpg->write_wq);
@@ -1413,6 +1442,7 @@ static int mtp_setup(void)
INIT_LIST_HEAD(&mtpg->rx_idle);
INIT_LIST_HEAD(&mtpg->rx_done);
INIT_LIST_HEAD(&mtpg->tx_idle);
+ INIT_LIST_HEAD(&mtpg->intr_idle);
/* the_mtpg must be set before calling usb_gadget_register_driver */
the_mtpg = mtpg;
diff --git a/drivers/video/samsung/Kconfig b/drivers/video/samsung/Kconfig
index 10d7474..3cb946f 100644
--- a/drivers/video/samsung/Kconfig
+++ b/drivers/video/samsung/Kconfig
@@ -154,7 +154,7 @@ config FB_S5P_S6F1202A
config FB_S5P_LD9040
bool "LD9040"
- depends on MACH_U1 || MACH_MIDAS
+ depends on MACH_U1 || MACH_MIDAS || MACH_TRATS
select LCD_CLASS_DEVICE
select SPI
select SPI_GPIO
@@ -164,7 +164,7 @@ config FB_S5P_LD9040
config FB_S5P_NT35560
bool "Sony NT35560"
- depends on MACH_U1 && !FB_S5P_MIPI_DSIM
+ depends on (MACH_U1 || MACH_TRATS) && !FB_S5P_MIPI_DSIM
select LCD_CLASS_DEVICE
select SPI
select SPI_GPIO
@@ -188,13 +188,13 @@ config FB_S5P_DUMMY_MIPI_LCD
config FB_S5P_S6E8AA0
bool "S6E8AA0 MIPI LCD"
- depends on (MACH_U1 || MACH_MIDAS) && FB_S5P_MIPI_DSIM
+ depends on FB_S5P_MIPI_DSIM
---help---
This enables support for Samsung S6E8AA0 MIPI LCD
config FB_S5P_S6E8AB0
bool "S6E8AB0 MIPI LCD"
- depends on MACH_P8 && FB_S5P_MIPI_DSIM
+ depends on MACH_PX && FB_S5P_MIPI_DSIM
---help---
This enables support for Samsung S6E8AB0 MIPI LCD
@@ -203,6 +203,30 @@ config FB_S5P_S6D6AA1
depends on FB_S5P_MIPI_DSIM
---help---
This enables support for Samsung S6D6AA1 MIPI LCD
+
+config FB_S5P_S6E63M0
+ bool "S6E63M0 MIPI LCD"
+ depends on (MACH_MIDAS) && FB_S5P_MIPI_DSIM
+ ---help---
+ This enables support for Samsung S6E63M0 MIPI LCD
+
+endchoice
+
+choice
+ prompt "Select PANEL Type"
+ depends on FB_S5P_S6E8AA0
+ default S6E8AA0_AMS480GYXX
+
+config S6E8AA0_AMS529HA01
+ bool "AMS529HA01(Q1)"
+ ---help---
+ This enables support for Samsung S6E8AA0 AMS529HA01(Q1) PANEL
+
+config S6E8AA0_AMS480GYXX
+ bool "AMS480GYXX(M0)"
+ ---help---
+ This enables support for Samsung S6E8AA0 AMS480GYXX(M0) PANEL
+
endchoice
config AID_DIMMING
diff --git a/drivers/video/samsung/lcdfreq.c b/drivers/video/samsung/lcdfreq.c
index 6895bf8..8c25c22 100644
--- a/drivers/video/samsung/lcdfreq.c
+++ b/drivers/video/samsung/lcdfreq.c
@@ -50,12 +50,7 @@ struct lcdfreq_info {
struct notifier_block pm_noti;
struct notifier_block reboot_noti;
- unsigned long time_stamp[LCDFREQ_LEVEL_END];
- unsigned long previous_time;
- unsigned long current_time;
-
struct delayed_work work;
- u32 count;
struct early_suspend early_suspend;
};
@@ -108,7 +103,7 @@ int set_div(struct s3cfb_global *ctrl, u32 div)
} while (count);
/* } while (time_before(jiffies, timeout)); */
- dev_err(ctrl->dev, "%s fail\n", __func__);
+ dev_err(ctrl->dev, "%s fail, div=%d\n", __func__, div);
return -EINVAL;
}
@@ -121,11 +116,12 @@ static int set_lcdfreq_div(struct device *dev, enum lcdfreq_level_idx level)
struct lcdfreq_info *lcdfreq = fbdev->data;
- u32 div = 0, ret = 0;
+ u32 div, ret;
mutex_lock(&lcdfreq->lock);
if (unlikely(fbdev->system_state == POWER_OFF || !lcdfreq->enable)) {
+ dev_err(dev, "%s reject. %d, %d\n", __func__, fbdev->system_state, lcdfreq->enable);
ret = -EINVAL;
goto exit;
}
@@ -135,7 +131,7 @@ static int set_lcdfreq_div(struct device *dev, enum lcdfreq_level_idx level)
ret = set_div(fbdev, div);
if (ret) {
- dev_info(dev, "fail to change lcd freq\n");
+ dev_err(dev, "fail to change lcd freq\n");
goto exit;
}
@@ -193,7 +189,6 @@ static int lcdfreq_lock_free(struct device *dev)
mutex_lock(&lcdfreq->lock);
atomic_dec(&lcdfreq->usage);
mutex_unlock(&lcdfreq->lock);
- lcdfreq->count = 0;
cancel_delayed_work(&lcdfreq->work);
}
@@ -229,7 +224,7 @@ int get_divider(struct fb_info *fb)
for (i = 0; i < LCDFREQ_LEVEL_END; i++) {
lcdfreq->table[i].cmu_clkdiv--;
- dev_info(fb->dev, "%dHz divider is %d\n",
+ dev_info(fb->dev, "%dHZ divider is %d\n",
lcdfreq->table[i].hz, lcdfreq->table[i].cmu_clkdiv);
}
@@ -256,6 +251,11 @@ static ssize_t level_show(struct device *dev,
struct s3cfb_global *fbdev = get_fimd_global(win->id);
struct lcdfreq_info *lcdfreq = fbdev->data;
+ if (unlikely(fbdev->system_state == POWER_OFF || !lcdfreq->enable)) {
+ dev_err(dev, "%s reject. %d, %d\n", __func__, fbdev->system_state, lcdfreq->enable);
+ return -EINVAL;
+ }
+
return sprintf(buf, "%dHZ, div=%d\n", lcdfreq->table[lcdfreq->level].hz, get_div(fbdev));
}
@@ -298,12 +298,10 @@ static ssize_t usage_show(struct device *dev,
static DEVICE_ATTR(level, S_IRUGO|S_IWUSR, level_show, level_store);
static DEVICE_ATTR(usage, S_IRUGO, usage_show, NULL);
-static DEVICE_ATTR(time_stamp, S_IRUGO, NULL, NULL);
static struct attribute *lcdfreq_attributes[] = {
&dev_attr_level.attr,
&dev_attr_usage.attr,
- &dev_attr_time_stamp.attr,
NULL,
};
@@ -390,17 +388,13 @@ static void lcdfreq_status_work(struct work_struct *work)
struct lcdfreq_info *lcdfreq =
container_of(work, struct lcdfreq_info, work.work);
-
u32 hz = lcdfreq->table[lcdfreq->level].hz;
cancel_delayed_work(&lcdfreq->work);
- if (!(lcdfreq->count % 2))
- dev_info(lcdfreq->dev, "\thz=%d, usage=%d\n", hz, atomic_read(&lcdfreq->usage));
-
- schedule_delayed_work(&lcdfreq->work, HZ*60);
+ dev_info(lcdfreq->dev, "\tHZ=%d, usage=%d\n", hz, atomic_read(&lcdfreq->usage));
- lcdfreq->count++;
+ schedule_delayed_work(&lcdfreq->work, HZ*120);
}
int lcdfreq_init(struct fb_info *fb)
@@ -425,7 +419,6 @@ int lcdfreq_init(struct fb_info *fb)
lcdfreq->dev = fb->dev;
lcdfreq->level = LEVEL_NORMAL;
- lcdfreq->previous_time = lcdfreq->current_time = jiffies;
vclk = (lcd->freq *
(var->left_margin + var->right_margin
diff --git a/drivers/video/samsung/mdnie.c b/drivers/video/samsung/mdnie.c
index bb672bd..d45d3e9 100644
--- a/drivers/video/samsung/mdnie.c
+++ b/drivers/video/samsung/mdnie.c
@@ -48,6 +48,8 @@
#else /* CONFIG_CPU_EXYNOS4210 */
#if defined(CONFIG_FB_S5P_S6E8AA0)
#include "mdnie_table_c1m0.h"
+#elif defined(CONFIG_FB_S5P_S6E63M0)
+#include "mdnie_table_c1m0.h"
#elif defined(CONFIG_FB_S5P_S6C1372)
#include "mdnie_table_p4note.h"
#elif defined(CONFIG_FB_S5P_S6D6AA1)
@@ -72,7 +74,7 @@
#define DIM_BACKLIGHT_VALUE 16
#define CABC_CUTOFF_BACKLIGHT_VALUE 40 /* 2.5% */
#elif defined(CONFIG_FB_S5P_S6C1372)
-#define MAX_BACKLIGHT_VALUE 1329
+#define MAX_BACKLIGHT_VALUE 1441 //90%
#define MID_BACKLIGHT_VALUE 784
#define LOW_BACKLIGHT_VALUE 16
#define DIM_BACKLIGHT_VALUE 16
@@ -104,15 +106,16 @@ struct class *mdnie_class;
struct mdnie_info *g_mdnie;
+#ifdef CONFIG_MACH_P4NOTE
+static struct mdnie_backlight_value b_value;
+#endif
+
int mdnie_send_sequence(struct mdnie_info *mdnie, const unsigned short *seq)
{
int ret = 0, i = 0;
const unsigned short *wbuf;
- if (!mdnie->enable) {
- dev_err(mdnie->dev, "do not configure mDNIe after LCD/mDNIe power off\n");
- return -EPERM;
- } else if (IS_ERR_OR_NULL(seq)) {
+ if (IS_ERR_OR_NULL(seq)) {
dev_err(mdnie->dev, "mdnie sequence is null\n");
return -EPERM;
}
@@ -135,12 +138,12 @@ int mdnie_send_sequence(struct mdnie_info *mdnie, const unsigned short *seq)
return ret;
}
-void set_mdnie_value(struct mdnie_info *mdnie)
+void set_mdnie_value(struct mdnie_info *mdnie, u8 force)
{
u8 idx;
- if (!mdnie->enable) {
- dev_err(mdnie->dev, "do not configure mDNIe after LCD/mDNIe power off\n");
+ if ((!mdnie->enable) && (!force)) {
+ dev_err(mdnie->dev, "mdnie states is off\n");
return;
}
@@ -152,7 +155,7 @@ void set_mdnie_value(struct mdnie_info *mdnie)
mdnie->tone = TONE_NORMAL;
if (mdnie->tunning) {
- dev_info(mdnie->dev, "mDNIe tunning mode is enabled\n");
+ dev_info(mdnie->dev, "mdnie tunning mode is enabled\n");
return;
}
@@ -200,7 +203,9 @@ void set_mdnie_value(struct mdnie_info *mdnie)
tunning_table[mdnie->cabc][mdnie->mode][mdnie->scenario].name);
}
+#if defined(CONFIG_TDMB) || defined(CONFIG_TARGET_LOCALE_NTT)
etc:
+#endif
if (!IS_ERR_OR_NULL(etc_table[mdnie->cabc][mdnie->outdoor][mdnie->tone].seq)) {
mdnie_send_sequence(mdnie, etc_table[mdnie->cabc][mdnie->outdoor][mdnie->tone].seq);
dev_info(mdnie->dev, "%s\n", etc_table[mdnie->cabc][mdnie->outdoor][mdnie->tone].name);
@@ -213,6 +218,34 @@ exit:
}
#if defined(CONFIG_FB_MDNIE_PWM)
+#ifdef CONFIG_MACH_P4NOTE
+static int get_backlight_level_from_brightness(unsigned int brightness)
+{
+ unsigned int value;
+
+ /* brightness tuning*/
+ if (brightness >= MID_BRIGHTNESS_LEVEL)
+ value = (brightness - MID_BRIGHTNESS_LEVEL) * (b_value.max-b_value.mid) / (MAX_BRIGHTNESS_LEVEL-MID_BRIGHTNESS_LEVEL) + b_value.mid;
+ else if (brightness >= LOW_BRIGHTNESS_LEVEL)
+ value = (brightness - LOW_BRIGHTNESS_LEVEL) * (b_value.mid-b_value.low) / (MID_BRIGHTNESS_LEVEL-LOW_BRIGHTNESS_LEVEL) + b_value.low;
+ else if (brightness >= DIM_BRIGHTNESS_LEVEL)
+ value = (brightness - DIM_BRIGHTNESS_LEVEL) * (b_value.low-b_value.dim) / (LOW_BRIGHTNESS_LEVEL-DIM_BRIGHTNESS_LEVEL) + b_value.dim;
+ else if (brightness > 0)
+ value = b_value.dim;
+ else
+ return 0;
+
+ if (value > 1600)
+ value = 1600;
+
+ if (value < 16)
+ value = 1;
+ else
+ value = value >> 4;
+
+ return value;
+}
+#else
static int get_backlight_level_from_brightness(unsigned int brightness)
{
unsigned int value;
@@ -227,7 +260,7 @@ static int get_backlight_level_from_brightness(unsigned int brightness)
else if (brightness > 0)
value = DIM_BACKLIGHT_VALUE;
else
- value = brightness;
+ return 0;
if (value > 1600)
value = 1600;
@@ -239,6 +272,7 @@ static int get_backlight_level_from_brightness(unsigned int brightness)
return value;
}
+#endif
#if defined(CONFIG_CPU_EXYNOS4210)
static void mdnie_pwm_control(struct mdnie_info *mdnie, int value)
@@ -283,8 +317,7 @@ static void mdnie_pwm_control_cabc(struct mdnie_info *mdnie, int value)
mutex_unlock(&mdnie->dev_lock);
}
-#endif
-#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#elif defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
static void mdnie_pwm_control(struct mdnie_info *mdnie, int value)
{
mutex_lock(&mdnie->dev_lock);
@@ -329,6 +362,11 @@ static void mdnie_pwm_control_cabc(struct mdnie_info *mdnie, int value)
}
#endif
+void set_mdnie_pwm_value(struct mdnie_info *mdnie, int value)
+{
+ mdnie_pwm_control(mdnie, value);
+}
+
static int update_brightness(struct mdnie_info *mdnie)
{
unsigned int value;
@@ -413,7 +451,7 @@ static ssize_t mode_store(struct device *dev,
mdnie->mode = value;
mutex_unlock(&mdnie->lock);
- set_mdnie_value(mdnie);
+ set_mdnie_value(mdnie, 0);
#if defined(CONFIG_FB_MDNIE_PWM)
if ((mdnie->enable) && (mdnie->bd_enable))
update_brightness(mdnie);
@@ -454,7 +492,7 @@ static ssize_t scenario_store(struct device *dev,
mdnie->scenario = value;
mutex_unlock(&mdnie->lock);
- set_mdnie_value(mdnie);
+ set_mdnie_value(mdnie, 0);
#if defined(CONFIG_FB_MDNIE_PWM)
if ((mdnie->enable) && (mdnie->bd_enable))
update_brightness(mdnie);
@@ -492,7 +530,7 @@ static ssize_t outdoor_store(struct device *dev,
mdnie->outdoor = value;
mutex_unlock(&mdnie->lock);
- set_mdnie_value(mdnie);
+ set_mdnie_value(mdnie, 0);
return count;
}
@@ -527,7 +565,7 @@ static ssize_t cabc_store(struct device *dev,
mdnie->cabc = value;
mutex_unlock(&mdnie->lock);
- set_mdnie_value(mdnie);
+ set_mdnie_value(mdnie, 0);
if ((mdnie->enable) && (mdnie->bd_enable))
update_brightness(mdnie);
@@ -609,7 +647,7 @@ static ssize_t negative_store(struct device *dev,
mdnie->negative = value;
mutex_unlock(&mdnie->lock);
- set_mdnie_value(mdnie);
+ set_mdnie_value(mdnie, 0);
}
return count;
}
@@ -756,6 +794,22 @@ static int mdnie_probe(struct platform_device *pdev)
#endif
#endif
+#if defined(CONFIG_FB_S5P_S6C1372)
+ check_lcd_type();
+ dev_info(mdnie->dev, "lcdtype = %d\n", pdata->display_type);
+ if (pdata->display_type == 1) {
+ b_value.max = 1441;
+ b_value.mid = 784;
+ b_value.low = 16;
+ b_value.dim = 16;
+ } else {
+ b_value.max = 1137; /* 71% */
+ b_value.mid = 482; /* 38% */
+ b_value.low = 16; /* 1% */
+ b_value.dim = 16; /* 1% */
+ }
+#endif
+
#if defined(CONFIG_FB_S5P_S6F1202A)
if (pdata->display_type == 0) {
memcpy(tunning_table, tunning_table_hy, sizeof(tunning_table));
@@ -777,7 +831,7 @@ static int mdnie_probe(struct platform_device *pdev)
g_mdnie = mdnie;
- set_mdnie_value(mdnie);
+ set_mdnie_value(mdnie, 0);
dev_info(mdnie->dev, "registered successfully\n");
diff --git a/drivers/video/samsung/mdnie.h b/drivers/video/samsung/mdnie.h
index f5098aa..4c37418 100644
--- a/drivers/video/samsung/mdnie.h
+++ b/drivers/video/samsung/mdnie.h
@@ -111,7 +111,18 @@ struct mdnie_info {
extern struct mdnie_info *g_mdnie;
int mdnie_send_sequence(struct mdnie_info *mdnie, const unsigned short *seq);
-extern void set_mdnie_value(struct mdnie_info *mdnie);
+extern void set_mdnie_value(struct mdnie_info *mdnie, u8 force);
+#if defined(CONFIG_FB_MDNIE_PWM)
+extern void set_mdnie_pwm_value(struct mdnie_info *mdnie, int value);
+#endif
extern int mdnie_txtbuf_to_parsing(char const *pFilepath);
+extern void check_lcd_type(void);
+struct mdnie_backlight_value {
+ unsigned int max;
+ unsigned int mid;
+ unsigned char low;
+ unsigned char dim;
+};
+
#endif /* __MDNIE_H__ */
diff --git a/drivers/video/samsung/s3cfb.h b/drivers/video/samsung/s3cfb.h
index 8f38995..fc4e10d 100644
--- a/drivers/video/samsung/s3cfb.h
+++ b/drivers/video/samsung/s3cfb.h
@@ -167,6 +167,7 @@ struct s3cfb_global {
void __iomem *ielcd_regs;
void *data;
struct mutex lock;
+ spinlock_t slock;
struct device *dev;
#ifdef CONFIG_BUSFREQ_OPP
struct device *bus_dev;
@@ -327,6 +328,7 @@ extern int s3cfb_set_window_control(struct s3cfb_global *ctrl, int id);
extern int s3cfb_set_alpha_mode(struct s3cfb_global *ctrl, int id, unsigned int mode);
extern int s3cfb_set_alpha_value_width(struct s3cfb_global *ctrl, int id);
extern int s3cfb_set_alpha_blending(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_set_oneshot(struct s3cfb_global *ctrl, int value);
extern int s3cfb_set_alpha_value(struct s3cfb_global *ctrl, int value);
extern int s3cfb_set_window_position(struct s3cfb_global *ctrl, int id);
extern int s3cfb_set_window_size(struct s3cfb_global *ctrl, int id);
@@ -336,12 +338,11 @@ extern int s3cfb_set_buffer_size(struct s3cfb_global *ctrl, int id);
extern int s3cfb_set_chroma_key(struct s3cfb_global *ctrl, int id);
extern int s3cfb_channel_localpath_on(struct s3cfb_global *ctrl, int id);
extern int s3cfb_channel_localpath_off(struct s3cfb_global *ctrl, int id);
-#ifdef CONFIG_FB_S5P_MIPI_DSIM
-extern void s3cfb_set_trigger(struct s3cfb_global *ctrl);
-extern void s3cfb_trigger(void);
-#endif
extern int s3cfb_check_vsync_status(struct s3cfb_global *ctrl);
+extern int s3cfb_set_dualrgb(struct s3cfb_global *ctrl, int mode);
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
extern int s3cfb_vsync_status_check(void);
+#endif
#ifdef CONFIG_HAS_WAKELOCK
#ifdef CONFIG_HAS_EARLYSUSPEND
@@ -356,11 +357,16 @@ extern void s3cfb_set_lcd_info(struct s3cfb_global *ctrl);
#ifdef CONFIG_FB_S5P_MIPI_DSIM
extern void s5p_dsim_early_suspend(void);
extern void s5p_dsim_late_resume(void);
+#ifdef CONFIG_FB_S5P_S6E63M0
+extern void s6e63m0_early_suspend(void);
+extern void s6e63m0_late_resume(void);
+#else
extern void s6e8ax0_early_suspend(void);
extern void s6e8ax0_late_resume(void);
+#endif
extern int s5p_dsim_fifo_clear(void);
extern void set_dsim_hs_clk_toggle_count(u8 count);
-extern void set_dsim_lcd_enabled(void);
+extern void set_dsim_lcd_enabled(u8 enable);
extern u32 read_dsim_register(u32 num);
#endif
@@ -374,7 +380,7 @@ extern void ams369fg06_gpio_cfg(void);
extern void lms501kf03_ldi_disable(void);
#endif
-#if defined(CONFIG_FB_S5P_S6C1372)
+#if defined(CONFIG_FB_S5P_S6C1372) || defined(CONFIG_FB_S5P_S6F1202A)
extern void s5c1372_ldi_enable(void);
extern void s5c1372_ldi_disable(void);
#endif
diff --git a/drivers/video/samsung/s3cfb_fimd6x.c b/drivers/video/samsung/s3cfb_fimd6x.c
index 3813852..71a24ae 100644
--- a/drivers/video/samsung/s3cfb_fimd6x.c
+++ b/drivers/video/samsung/s3cfb_fimd6x.c
@@ -41,7 +41,14 @@ void s3cfb_check_line_count(struct s3cfb_global *ctrl)
int s3cfb_check_vsync_status(struct s3cfb_global *ctrl)
{
- u32 cfg = (readl(ctrl->regs + S3C_VIDCON1) & S3C_VIDCON1_VSTATUS_MASK);
+ u32 cfg;
+
+ if (unlikely(!ctrl->regs)) {
+ dev_err(ctrl->dev, "reg is zero\n");
+ return 0;
+ }
+
+ cfg = (readl(ctrl->regs + S3C_VIDCON1) & S3C_VIDCON1_VSTATUS_MASK);
if (cfg != S3C_VIDCON1_VSTATUS_ACTIVE && cfg != S3C_VIDCON1_VSTATUS_BACK)
return 1;
@@ -794,6 +801,76 @@ int s3cfb_set_alpha_blending(struct s3cfb_global *ctrl, int id)
return 0;
}
+int s3cfb_set_oneshot(struct s3cfb_global *ctrl, int id)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
+ struct fb_fix_screeninfo *fix = &ctrl->fb[id]->fix;
+ struct s3cfb_window *win = ctrl->fb[id]->par;
+ u32 cfg, shw;
+ u32 offset = (var->xres_virtual - var->xres) * var->bits_per_pixel / 8;
+ dma_addr_t start_addr = 0, end_addr = 0;
+
+ /* Shadow Register Protection */
+ if ((pdata->hw_ver == 0x62) || (pdata->hw_ver == 0x70)) {
+ shw = readl(ctrl->regs + S3C_WINSHMAP);
+ shw |= S3C_WINSHMAP_PROTECT(id);
+ writel(shw, ctrl->regs + S3C_WINSHMAP);
+ }
+
+ /* s3cfb_set_window_position */
+ cfg = S3C_VIDOSD_LEFT_X(win->x) | S3C_VIDOSD_TOP_Y(win->y);
+ writel(cfg, ctrl->regs + S3C_VIDOSD_A(id));
+
+ cfg = S3C_VIDOSD_RIGHT_X(win->x + var->xres - 1) |
+ S3C_VIDOSD_BOTTOM_Y(win->y + var->yres - 1);
+ writel(cfg, ctrl->regs + S3C_VIDOSD_B(id));
+
+ dev_dbg(ctrl->dev, "[fb%d] offset: (%d, %d, %d, %d)\n", id,
+ win->x, win->y, win->x + var->xres - 1, win->y + var->yres - 1);
+
+ /* s3cfb_set_buffer_address */
+ if (fix->smem_start) {
+ start_addr = fix->smem_start + ((var->xres_virtual *
+ var->yoffset + var->xoffset) *
+ (var->bits_per_pixel / 8));
+
+ end_addr = start_addr + fix->line_length * var->yres;
+ }
+
+ writel(start_addr, ctrl->regs + S3C_VIDADDR_START0(id));
+ writel(end_addr, ctrl->regs + S3C_VIDADDR_END0(id));
+
+ dev_dbg(ctrl->dev, "[fb%d] start_addr: 0x%08x, end_addr: 0x%08x\n",
+ id, start_addr, end_addr);
+
+ /* s3cfb_set_window_size */
+ if (id <= 2) {
+ cfg = S3C_VIDOSD_SIZE(var->xres * var->yres);
+ if (id == 0)
+ writel(cfg, ctrl->regs + S3C_VIDOSD_C(id));
+ else
+ writel(cfg, ctrl->regs + S3C_VIDOSD_D(id));
+
+ dev_dbg(ctrl->dev, "[fb%d] resolution: %d x %d\n", id,
+ var->xres, var->yres);
+ }
+
+ /* s3cfb_set_buffer_size */
+ cfg = S3C_VIDADDR_PAGEWIDTH(var->xres * var->bits_per_pixel / 8);
+ cfg |= S3C_VIDADDR_OFFSIZE(offset);
+ writel(cfg, ctrl->regs + S3C_VIDADDR_SIZE(id));
+
+ /* Shadow Register Un-Protection */
+ if ((pdata->hw_ver == 0x62) || (pdata->hw_ver == 0x70)) {
+ shw = readl(ctrl->regs + S3C_WINSHMAP);
+ shw &= ~(S3C_WINSHMAP_PROTECT(id));
+ writel(shw, ctrl->regs + S3C_WINSHMAP);
+ }
+
+ return 0;
+}
+
int s3cfb_set_window_position(struct s3cfb_global *ctrl, int id)
{
struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
@@ -911,3 +988,11 @@ int s3cfb_set_chroma_key(struct s3cfb_global *ctrl, int id)
return 0;
}
+
+int s3cfb_set_dualrgb(struct s3cfb_global *ctrl, int mode)
+{
+ writel(mode, ctrl->regs + S3C_DUALRGB);
+
+ return 0;
+}
+
diff --git a/drivers/video/samsung/s3cfb_ielcd.c b/drivers/video/samsung/s3cfb_ielcd.c
index 9550327..b86d6f5 100644
--- a/drivers/video/samsung/s3cfb_ielcd.c
+++ b/drivers/video/samsung/s3cfb_ielcd.c
@@ -78,7 +78,7 @@ int s3c_ielcd_logic_stop(void)
return 0;
}
-int s3c_ielcd_start(void)
+int s3c_ielcd_display_on(void)
{
unsigned int cfg;
@@ -90,7 +90,7 @@ int s3c_ielcd_start(void)
}
#if 0
-int s3c_ielcd_stop(void)
+int s3c_ielcd_display_off(void)
{
unsigned int cfg;
@@ -102,13 +102,13 @@ int s3c_ielcd_stop(void)
return 0;
}
#else
-int s3c_ielcd_stop(void)
+int s3c_ielcd_display_off(void)
{
- unsigned int cfg = 0, ielcd_count = 0;
+ unsigned int cfg, ielcd_count = 0;
cfg = s3c_ielcd_readl(S3C_VIDCON0);
cfg |= S3C_VIDCON0_ENVID_ENABLE;
- cfg &= ~S3C_VIDCON0_ENVID_F_ENABLE;
+ cfg &= ~(S3C_VIDCON0_ENVID_F_ENABLE);
s3c_ielcd_writel(cfg, S3C_VIDCON0);
@@ -121,7 +121,6 @@ int s3c_ielcd_stop(void)
if (!(s3c_ielcd_readl(S3C_VIDCON1) & 0xffff0000))
return 0;
} while (1);
-
}
#endif
@@ -136,31 +135,26 @@ int s3c_ielcd_init_global(struct s3cfb_global *ctrl)
s3cfb_set_timing(ielcd_fbdev);
s3cfb_set_lcd_size(ielcd_fbdev);
- s3c_ielcd_writel(0, S3C_DITHMODE);
-
+ /* vclock divider setting , same as FIMD */
cfg = readl(ctrl->regs + S3C_VIDCON0);
- cfg &= ~(S3C_VIDCON0_VIDOUT_MASK | S3C_VIDCON0_VCLKEN_MASK | S3C_VIDCON0_ENVID_F_ENABLE);
+ cfg &= ~(S3C_VIDCON0_VIDOUT_MASK | S3C_VIDCON0_VCLKEN_MASK);
cfg |= S3C_VIDCON0_VIDOUT_RGB;
-#ifdef CONFIG_FB_S5P_MIPI_DSIM
cfg |= S3C_VIDCON0_VCLKEN_NORMAL;
-#else
- cfg |= S3C_VIDCON0_VCLKEN_FREERUN;
-#endif
s3c_ielcd_writel(cfg, S3C_VIDCON0);
- /* s3c_ielcd_writel(1<<5, S3C_VIDINTCON0); */ /* for what? */
-
- s3cfb_set_vsync_interrupt(ielcd_fbdev, 0);
- s3cfb_set_global_interrupt(ielcd_fbdev, 0);
-
+ /* window0 position setting , fixed */
s3c_ielcd_writel(0, S3C_VIDOSD0A);
+
+ /* window0 position setting */
cfg = S3C_VIDOSD_RIGHT_X(ctrl->lcd->width - 1);
cfg |= S3C_VIDOSD_BOTTOM_Y(ctrl->lcd->height - 1);
s3c_ielcd_writel(cfg, S3C_VIDOSD0B);
+
+ /* window0 osd size setting */
s3c_ielcd_writel((ctrl->lcd->width * ctrl->lcd->height), S3C_VIDOSD0C);
- cfg = S3C_WINCON_DATAPATH_LOCAL | S3C_WINCON_BPPMODE_32BPP;
- cfg |= S3C_WINCON_INRGB_RGB;
+ /* window0 setting , fixed */
+ cfg = S3C_WINCON_DATAPATH_LOCAL | S3C_WINCON_BPPMODE_32BPP | S3C_WINCON_INRGB_RGB;
s3c_ielcd_writel(cfg, S3C_WINCON0);
s3cfb_window_on(ielcd_fbdev, 0);
diff --git a/drivers/video/samsung/s3cfb_ielcd.h b/drivers/video/samsung/s3cfb_ielcd.h
index 0684a7f..e5b637b 100644
--- a/drivers/video/samsung/s3cfb_ielcd.h
+++ b/drivers/video/samsung/s3cfb_ielcd.h
@@ -23,8 +23,8 @@
int s3c_ielcd_hw_init(void);
int s3c_ielcd_logic_start(void);
int s3c_ielcd_logic_stop(void);
-int s3c_ielcd_start(void);
-int s3c_ielcd_stop(void);
+int s3c_ielcd_display_on(void);
+int s3c_ielcd_display_off(void);
int s3c_ielcd_init_global(struct s3cfb_global *ctrl);
diff --git a/drivers/video/samsung/s3cfb_main.c b/drivers/video/samsung/s3cfb_main.c
index 3abbb4c..a6e4564 100644
--- a/drivers/video/samsung/s3cfb_main.c
+++ b/drivers/video/samsung/s3cfb_main.c
@@ -192,6 +192,7 @@ void read_lcd_register(void)
(i*16), reg_val[i*4], reg_val[i*4+1], reg_val[i*4+2], reg_val[i*4+3]);
#endif
}
+
static int s3cfb_sysfs_show_win_power(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -289,15 +290,15 @@ static ssize_t fimd_dump_show(struct device *dev,
}
static DEVICE_ATTR(fimd_dump, 0444, fimd_dump_show, NULL);
-#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#if 0 /* def CONFIG_FB_S5P_MIPI_DSIM */
void s3cfb_display_on_remote(void)
{
struct s3cfb_global *fbdev = fbfimd->fbdev[0];
struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
if (pdata == NULL) {
- dev_err(fbdev->dev, "failed to get defualt window number.\n");
- return;
+ dev_err(fbdev->dev, "failed to get defualt window number.\n");
+ return;
}
s3cfb_display_on(fbdev);
}
@@ -324,7 +325,6 @@ static int s3cfb_probe(struct platform_device *pdev)
struct s3cfb_global *fbdev[2];
int ret = 0;
int i = 0;
- u32 reg;
#ifdef CONFIG_EXYNOS_DEV_PD
/* to use the runtime PM helper functions */
@@ -421,6 +421,8 @@ static int s3cfb_probe(struct platform_device *pdev)
fbdev[i]->system_state = POWER_ON;
+ spin_lock_init(&fbdev[i]->slock);
+
/* alloc fb_info */
if (s3cfb_alloc_framebuffer(fbdev[i], i)) {
dev_err(fbdev[i]->dev, "alloc error fimd[%d]\n", i);
@@ -440,20 +442,14 @@ static int s3cfb_probe(struct platform_device *pdev)
#ifdef CONFIG_FB_S5P_MDNIE
/* only FIMD0 is supported */
if (i == 0) {
- reg = readl(S3C_VA_SYS + 0x0210);
- reg &= ~(1<<13);
- reg &= ~(1<<12);
- reg &= ~(3<<10);
- reg |= (1<<0);
- reg &= ~(1<<1);
- writel(reg, S3C_VA_SYS + 0x0210);
- writel(3, fbdev[i]->regs + 0x27c);
+ if (pdata->set_display_path)
+ pdata->set_display_path();
+ s3cfb_set_dualrgb(fbdev[i], S3C_DUALRGB_MDNIE);
s3c_mdnie_init_global(fbdev[i]);
- s3c_mdnie_start(fbdev[i]);
+ s3c_mdnie_display_on(fbdev[i]);
}
#endif
-
s3cfb_enable_window(fbdev[0], pdata->default_win);
s3cfb_update_power_state(fbdev[i], pdata->default_win,
@@ -462,9 +458,7 @@ static int s3cfb_probe(struct platform_device *pdev)
/* Set alpha value width to 8-bit */
s3cfb_set_alpha_value_width(fbdev[i], i);
-#ifndef CONFIG_MACH_JENGA
s3cfb_display_on(fbdev[i]);
-#endif
#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
#ifdef CONFIG_BUSFREQ_OPP
@@ -654,7 +648,7 @@ void s3cfb_lcd0_power_domain_stop(void)
void s3cfb_lcd0_pmu_off(void)
{
s3cfb_lcd0_power_domain_stop();
- msleep(5);
+ usleep_range(5000, 5000);
s3cfb_lcd0_power_domain_start();
printk(KERN_WARNING "lcd0 pmu re_start!!!\n");
}
@@ -668,13 +662,16 @@ void s3cfb_early_suspend(struct early_suspend *h)
struct platform_device *pdev = to_platform_device(info->dev);
struct s3cfb_global *fbdev[2];
int i, ret;
- u32 reg;
printk(KERN_INFO "+%s\n", __func__);
-#if defined(CONFIG_FB_S5P_S6E8AA0) || defined(CONFIG_FB_S5P_S6E8AB0) || defined(CONFIG_FB_S5P_S6D6AA1)
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#if defined(CONFIG_FB_S5P_S6E63M0)
+ s6e63m0_early_suspend();
+#else
s6e8ax0_early_suspend();
#endif
+#endif
for (i = 0; i < FIMD_MAX; i++) {
fbdev[i] = fbfimd->fbdev[i];
@@ -694,36 +691,29 @@ void s3cfb_early_suspend(struct early_suspend *h)
#elif defined(CONFIG_FB_S5P_LMS501KF03)
lms501kf03_ldi_disable();
#endif
-
ret = s3cfb_display_off(fbdev[i]);
#ifdef CONFIG_FB_S5P_MDNIE
- ret += s3c_mdnie_stop();
+ ret += s3c_mdnie_display_off();
#endif
if (ret > 0)
s3cfb_lcd0_pmu_off();
-#ifdef CONFIG_FB_S5P_MDNIE
- writel(0, fbdev[i]->regs + 0x27c);
- msleep(20);
- reg = readl(S3C_VA_SYS + 0x0210);
- reg |= (1<<1);
- writel(reg, S3C_VA_SYS + 0x0210);
-#endif
-
info->system_state = POWER_OFF;
if (fbdev[i]->regs) {
fbdev[i]->regs_org = fbdev[i]->regs;
+ spin_lock(&fbdev[i]->slock);
fbdev[i]->regs = 0;
+ spin_unlock(&fbdev[i]->slock);
}
if (pdata->clk_off)
pdata->clk_off(pdev, &fbdev[i]->clock);
}
-#if defined(CONFIG_FB_S5P_S6C1372)
+#if defined(CONFIG_FB_S5P_S6C1372) || defined(CONFIG_FB_S5P_S6F1202A)
s5c1372_ldi_disable();
#endif
@@ -750,7 +740,6 @@ void s3cfb_late_resume(struct early_suspend *h)
struct s3cfb_global *fbdev[2];
int i, j;
struct platform_device *pdev = to_platform_device(info->dev);
- u32 reg;
printk(KERN_INFO "+%s\n", __func__);
@@ -767,13 +756,13 @@ void s3cfb_late_resume(struct early_suspend *h)
if (s5p_dsim_fifo_clear() == 0) {
s5p_dsim_early_suspend();
- msleep(10);
+ usleep_range(10000, 10000);
s5p_dsim_late_resume();
if (s5p_dsim_fifo_clear() == 0)
pr_info("dsim resume fail!!!\n");
}
- msleep(10);
+ usleep_range(10000, 10000);
#endif
#if defined(CONFIG_FB_S5P_DUMMYLCD)
@@ -791,18 +780,15 @@ void s3cfb_late_resume(struct early_suspend *h)
/* fbdev[i]->regs_org should be non-zero value */
BUG();
- info->system_state = POWER_ON;
+ if (pdata->set_display_path)
+ pdata->set_display_path();
#ifdef CONFIG_FB_S5P_MDNIE
- reg = readl(S3C_VA_SYS + 0x0210);
- reg &= ~(1<<13);
- reg &= ~(1<<12);
- reg &= ~(3<<10);
- reg |= (1<<0);
- reg &= ~(1<<1);
- writel(reg, S3C_VA_SYS + 0x0210);
- writel(3, fbdev[i]->regs + 0x27c);
+ s3cfb_set_dualrgb(fbdev[i], S3C_DUALRGB_MDNIE);
#endif
+
+ info->system_state = POWER_ON;
+
s3cfb_init_global(fbdev[i]);
s3cfb_set_clock(fbdev[i]);
/* Set Alpha value width to 8-bit alpha value
@@ -810,18 +796,15 @@ void s3cfb_late_resume(struct early_suspend *h)
* 2 : 4bit mode
*/
s3cfb_set_alpha_value(fbdev[i], 1);
-#if defined(CONFIG_FB_S5P_S6C1372)
+#ifdef CONFIG_FB_S5P_MDNIE
+#if defined(CONFIG_FB_S5P_S6C1372) || defined(CONFIG_FB_S5P_S6F1202A)
s5c1372_ldi_enable();
#endif
-
-#ifdef CONFIG_FB_S5P_MDNIE
s3c_mdnie_init_global(fbdev[i]);
- s3c_mdnie_start(fbdev[i]);
+ set_mdnie_value(g_mdnie, 1);
+ s3c_mdnie_display_on(fbdev[i]);
#endif
s3cfb_display_on(fbdev[i]);
-#ifdef CONFIG_FB_S5P_MDNIE
- set_mdnie_value(g_mdnie);
-#endif
/* Set alpha value width to 8-bit */
s3cfb_set_alpha_value_width(fbdev[i], i);
@@ -836,11 +819,6 @@ void s3cfb_late_resume(struct early_suspend *h)
}
}
-#ifdef CONFIG_FB_S5P_AMS369FG06
- ams369fg06_gpio_cfg();
- ams369fg06_ldi_init();
- ams369fg06_ldi_enable();
-#endif
if (pdata->cfg_gpio)
pdata->cfg_gpio(pdev);
@@ -854,9 +832,13 @@ void s3cfb_late_resume(struct early_suspend *h)
pdata->backlight_on(pdev);
}
-#if defined(CONFIG_FB_S5P_S6E8AA0) || defined(CONFIG_FB_S5P_S6E8AB0) || defined(CONFIG_FB_S5P_S6D6AA1)
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#if defined(CONFIG_FB_S5P_S6E63M0)
+ s6e63m0_late_resume();
+#else
s6e8ax0_late_resume();
#endif
+#endif
printk(KERN_INFO "-%s\n", __func__);
@@ -880,7 +862,7 @@ int s3cfb_suspend(struct platform_device *pdev, pm_message_t state)
reg = readl(S3C_VA_SYS + 0x0210);
reg |= (1<<1);
writel(reg, S3C_VA_SYS + 0x0210);
- s3c_mdnie_stop();
+ s3c_mdnie_display_off();
#endif
if (atomic_read(&fbdev[i]->enabled_win) > 0) {
/* lcd_off and backlight_off isn't needed. */
@@ -956,7 +938,7 @@ int s3cfb_resume(struct platform_device *pdev)
s3cfb_set_clock(fbdev[i]);
#ifdef CONFIG_FB_S5P_MDNIE
s3c_mdnie_init_global(fbdev[i]);
- s3c_mdnie_start(fbdev[i]);
+ s3c_mdnie_display_on(fbdev[i]);
#endif
for (j = 0; j < pdata->nr_wins; j++) {
fb = fbdev[i]->fb[j];
@@ -974,9 +956,7 @@ int s3cfb_resume(struct platform_device *pdev)
s3cfb_set_alpha_value_width(fbdev[i], i);
-#ifndef CONFIG_MACH_JENGA
s3cfb_display_on(fbdev[i]);
-#endif
if (pdata->backlight_on)
pdata->backlight_on(pdev);
diff --git a/drivers/video/samsung/s3cfb_mdnie.c b/drivers/video/samsung/s3cfb_mdnie.c
index 6860e59..0fa2f60 100644
--- a/drivers/video/samsung/s3cfb_mdnie.c
+++ b/drivers/video/samsung/s3cfb_mdnie.c
@@ -146,9 +146,9 @@ int s3c_mdnie_init_global(struct s3cfb_global *s3cfb_ctrl)
return 0;
}
-int s3c_mdnie_start(struct s3cfb_global *ctrl)
+int s3c_mdnie_display_on(struct s3cfb_global *ctrl)
{
- s3c_ielcd_start();
+ s3c_ielcd_display_on();
if (!IS_ERR_OR_NULL(g_mdnie))
g_mdnie->enable = TRUE;
@@ -156,22 +156,22 @@ int s3c_mdnie_start(struct s3cfb_global *ctrl)
return 0;
}
-int s3c_mdnie_off(void)
+int s3c_mdnie_display_off(void)
{
if (!IS_ERR_OR_NULL(g_mdnie))
g_mdnie->enable = FALSE;
- s3c_ielcd_logic_stop();
-
- return 0;
+ return s3c_ielcd_display_off();
}
-int s3c_mdnie_stop(void)
+int s3c_mdnie_off(void)
{
if (!IS_ERR_OR_NULL(g_mdnie))
g_mdnie->enable = FALSE;
- return s3c_ielcd_stop();
+ s3c_ielcd_logic_stop();
+
+ return 0;
}
int s3c_mdnie_hw_init(void)
diff --git a/drivers/video/samsung/s3cfb_mdnie.h b/drivers/video/samsung/s3cfb_mdnie.h
index 962b342..329a40a 100644
--- a/drivers/video/samsung/s3cfb_mdnie.h
+++ b/drivers/video/samsung/s3cfb_mdnie.h
@@ -326,9 +326,9 @@
int s3c_mdnie_setup(void);
int s3c_mdnie_init_global(struct s3cfb_global *s3cfb_ctrl);
-int s3c_mdnie_start(struct s3cfb_global *ctrl);
+int s3c_mdnie_display_on(struct s3cfb_global *ctrl);
+int s3c_mdnie_display_off(void);
int s3c_mdnie_off(void);
-int s3c_mdnie_stop(void);
int mdnie_write(unsigned int addr, unsigned int val);
int s3c_mdnie_mask(void);
diff --git a/drivers/video/samsung/s3cfb_ops.c b/drivers/video/samsung/s3cfb_ops.c
index c6cfab3..3ff2f05 100644
--- a/drivers/video/samsung/s3cfb_ops.c
+++ b/drivers/video/samsung/s3cfb_ops.c
@@ -104,15 +104,12 @@ int s3cfb_draw_logo(struct fb_info *fb)
#else /* #ifdef RGB_BOOTSCREEN */
u8 *logo_virt_buf;
- if (bootloaderfb)
- printk(KERN_INFO "Bootloader sent 'bootloaderfb' to Kernel Successfully : %d", bootloaderfb);
- else {
- bootloaderfb = BOOT_FB_BASE_ADDR;
- printk(KERN_ERR "Fail to get 'bootloaderfb' from Bootloader. so we must set this value as %d", bootloaderfb);
+ if (bootloaderfb) {
+ logo_virt_buf = phys_to_virt(bootloaderfb);
+ memcpy(fb->screen_base, logo_virt_buf, fb->var.yres * fb->fix.line_length);
+ printk(KERN_INFO "Bootloader sent 'bootloaderfb' : %08X\n", bootloaderfb);
}
- logo_virt_buf = phys_to_virt(bootloaderfb);
- memcpy(fb->screen_base, logo_virt_buf, fb->var.yres * fb->fix.line_length);
#endif /* #ifdef RGB_BOOTSCREEN */
#endif
#endif
@@ -393,7 +390,8 @@ int s3cfb_map_default_video_memory(struct s3cfb_global *fbdev,
(unsigned int)fix->smem_start,
(unsigned int)fb->screen_base, fix->smem_len);
- memset(fb->screen_base, 0, fix->smem_len);
+ if (bootloaderfb)
+ memset(fb->screen_base, 0, fix->smem_len);
win->owner = DMA_MEM_FIMD;
return 0;
@@ -552,10 +550,14 @@ int s3cfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
void s3cfb_set_win_params(struct s3cfb_global *fbdev, int id)
{
s3cfb_set_window_control(fbdev, id);
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ s3cfb_set_oneshot(fbdev, id);
+#else
s3cfb_set_window_position(fbdev, id);
s3cfb_set_window_size(fbdev, id);
s3cfb_set_buffer_address(fbdev, id);
s3cfb_set_buffer_size(fbdev, id);
+#endif
if (id > 0) {
s3cfb_set_alpha_blending(fbdev, id);
@@ -1031,22 +1033,32 @@ int s3cfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb)
{
struct s3cfb_window *win = fb->par;
struct s3cfb_global *fbdev = get_fimd_global(win->id);
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+
+ if (win->id == pdata->default_win)
+ spin_lock(&fbdev->slock);
#ifdef CONFIG_EXYNOS_DEV_PD
if (unlikely(fbdev->system_state == POWER_OFF) || fbdev->regs == 0) {
dev_err(fbdev->dev, "%s::system_state is POWER_OFF, fb%d\n", __func__, win->id);
- return 0;
+ if (win->id == pdata->default_win)
+ spin_unlock(&fbdev->slock);
+ return -EINVAL;
}
#endif
if (var->yoffset + var->yres > var->yres_virtual) {
dev_err(fbdev->dev, "invalid yoffset value\n");
+ if (win->id == pdata->default_win)
+ spin_unlock(&fbdev->slock);
return -EINVAL;
}
#if defined(CONFIG_CPU_EXYNOS4210)
if (unlikely(var->xoffset + var->xres > var->xres_virtual)) {
dev_err(fbdev->dev, "invalid xoffset value\n");
+ if (win->id == pdata->default_win)
+ spin_unlock(&fbdev->slock);
return -EINVAL;
}
fb->var.xoffset = var->xoffset;
@@ -1059,6 +1071,8 @@ int s3cfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb)
s3cfb_set_buffer_address(fbdev, win->id);
+ if (win->id == pdata->default_win)
+ spin_unlock(&fbdev->slock);
return 0;
}
@@ -1143,6 +1157,10 @@ int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
sizeof(p.user_window)))
ret = -EFAULT;
else {
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ win->x = p.user_window.x;
+ win->y = p.user_window.y;
+#else
if (p.user_window.x < 0)
p.user_window.x = 0;
@@ -1160,6 +1178,7 @@ int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
win->y = p.user_window.y;
s3cfb_set_window_position(fbdev, win->id);
+#endif
}
break;
diff --git a/drivers/video/samsung/s3cfb_s6e39a0.c b/drivers/video/samsung/s3cfb_s6e39a0.c
index 4e9fa8f..3d0f534 100644
--- a/drivers/video/samsung/s3cfb_s6e39a0.c
+++ b/drivers/video/samsung/s3cfb_s6e39a0.c
@@ -106,9 +106,9 @@ struct lcd_info {
#endif
unsigned int irq;
unsigned int connected;
-};
-static struct mipi_ddi_platform_data *ddi_pd;
+ struct dsim_global *dsim;
+};
static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
@@ -124,11 +124,11 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
wbuf = seq;
if (size == 1)
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_WR_NO_PARA, wbuf[0], 0);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
else if (size == 2)
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
else
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_LONG_WR, (unsigned int)wbuf, size);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
mutex_unlock(&lcd->lock);
@@ -144,44 +144,14 @@ static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
mutex_lock(&lcd->lock);
- if (ddi_pd->cmd_read)
- ret = ddi_pd->cmd_read(ddi_pd->dsim_base, addr, count, buf);
+ if (lcd->dsim->ops->cmd_read)
+ ret = lcd->dsim->ops->cmd_read(lcd->dsim, addr, count, buf);
mutex_unlock(&lcd->lock);
return ret;
}
-static int s6e8ax0_set_link(void *pd, unsigned int dsim_base,
- unsigned char (*cmd_write) (unsigned int dsim_base, unsigned int data0,
- unsigned int data1, unsigned int data2),
- int (*cmd_read) (unsigned int reg_base, u8 addr, u16 count, u8 *buf))
-{
- struct mipi_ddi_platform_data *temp_pd = NULL;
-
- temp_pd = (struct mipi_ddi_platform_data *) pd;
- if (temp_pd == NULL) {
- printk(KERN_ERR "mipi_ddi_platform_data is null.\n");
- return -EPERM;
- }
-
- ddi_pd = temp_pd;
-
- ddi_pd->dsim_base = dsim_base;
-
- if (cmd_write)
- ddi_pd->cmd_write = cmd_write;
- else
- printk(KERN_WARNING "cmd_write function is null.\n");
-
- if (cmd_read)
- ddi_pd->cmd_read = cmd_read;
- else
- printk(KERN_WARNING "cmd_read function is null.\n");
-
- return 0;
-}
-
static int get_backlight_level_from_brightness(int brightness)
{
int backlightlevel;
@@ -362,8 +332,7 @@ static int update_brightness(struct lcd_info *lcd)
{
int ret;
-#if defined(CONFIG_MACH_MIDAS_01_BD) || defined(CONFIG_MACH_MIDAS_02_BD) || \
- defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_PQ) || \
defined(CONFIG_MACH_SLP_PQ_LTE) || defined(CONFIG_MACH_M3)
#else
@@ -956,8 +925,7 @@ static void s6e8aa0_check_id(struct lcd_info *lcd, u8 *idbuf)
lcd->elvss.reference = lcd->smart.panelid[2];
printk(KERN_DEBUG "Dynamic ELVSS Information\n");
- printk(KERN_DEBUG "Refrence : %02x , manual_version = %02x,\
- lcd->aid= %02x\n", lcd->elvss.reference, lcd->manual_version, lcd->aid);
+ printk(KERN_DEBUG "Refrence : %02x , manual_version = %02x, lcd->aid= %02x\n", lcd->elvss.reference, lcd->manual_version, lcd->aid);
} else if ((idbuf[0] == PANEL_A1_M3) || (idbuf[0] == PANEL_A2_M3)) {
lcd->support_elvss = 0;
printk(KERN_DEBUG "ID-3 is 0xff does not support dynamic elvss\n");
@@ -1003,6 +971,7 @@ static int s6e8ax0_probe(struct device *dev)
}
lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
lcd->bl = DEFAULT_GAMMA_LEVEL;
@@ -1103,7 +1072,6 @@ static void s6e8ax0_shutdown(struct device *dev)
static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
.name = "s6e8aa0",
- .set_link = s6e8ax0_set_link,
.probe = s6e8ax0_probe,
.remove = __devexit_p(s6e8ax0_remove),
.shutdown = s6e8ax0_shutdown,
diff --git a/drivers/video/samsung/s3cfb_s6e8aa0.c b/drivers/video/samsung/s3cfb_s6e8aa0.c
index e9581e9..987b215 100644
--- a/drivers/video/samsung/s3cfb_s6e8aa0.c
+++ b/drivers/video/samsung/s3cfb_s6e8aa0.c
@@ -34,7 +34,7 @@
#include "s3cfb.h"
#include "s6e8aa0_gamma_l.h"
-#if defined(CONFIG_MACH_Q1_BD)
+#if defined(CONFIG_S6E8AA0_AMS529HA01)
#include "s6e8aa0_gamma_q1.h"
#define SMART_DIMMING
#else
@@ -53,7 +53,7 @@
#define MIN_BRIGHTNESS 0
#define MAX_BRIGHTNESS 255
-#if defined(CONFIG_MACH_Q1_BD)
+#if defined(CONFIG_S6E8AA0_AMS529HA01)
#define MAX_GAMMA 290
#define DEFAULT_BRIGHTNESS 150
#define DEFAULT_GAMMA_LEVEL GAMMA_150CD
@@ -122,13 +122,12 @@ struct lcd_info {
unsigned int connected;
#if defined(GPIO_OLED_DET)
- struct delayed_work hs_clk_toggle;
- unsigned int esd_detection_count;
+ struct delayed_work oled_detection;
+ unsigned int oled_detection_count;
#endif
+ struct dsim_global *dsim;
};
-static struct mipi_ddi_platform_data *ddi_pd;
-
#ifdef CONFIG_AID_DIMMING
static const unsigned int candela_table[GAMMA_MAX] = {
20, 30, 40, 50, 60, 70, 80, 90, 100,
@@ -183,19 +182,19 @@ static unsigned int elvss_offset_table[ELVSS_STATUS_MAX] = {
#endif
#if defined(GPIO_OLED_DET)
-static void hs_clk_toggle_work(struct work_struct *work)
+static void oled_detection_work(struct work_struct *work)
{
struct lcd_info *lcd =
- container_of(work, struct lcd_info, hs_clk_toggle.work);
+ container_of(work, struct lcd_info, oled_detection.work);
int oled_det_level = gpio_get_value(GPIO_OLED_DET);
- printk(KERN_INFO "%s, %d, %d\n", __func__, lcd->esd_detection_count, oled_det_level);
+ dev_info(&lcd->ld->dev, "%s, %d, %d\n", __func__, lcd->oled_detection_count, oled_det_level);
if (!oled_det_level) {
- if (lcd->esd_detection_count < 10) {
- schedule_delayed_work(&lcd->hs_clk_toggle, HZ/8);
- lcd->esd_detection_count++;
+ if (lcd->oled_detection_count < 10) {
+ schedule_delayed_work(&lcd->oled_detection, HZ/8);
+ lcd->oled_detection_count++;
set_dsim_hs_clk_toggle_count(15);
} else
set_dsim_hs_clk_toggle_count(0);
@@ -204,14 +203,14 @@ static void hs_clk_toggle_work(struct work_struct *work)
}
-static irqreturn_t oled_det_int(int irq, void *_lcd)
+static irqreturn_t oled_detection_int(int irq, void *_lcd)
{
struct lcd_info *lcd = _lcd;
- printk(KERN_INFO "%s\n", __func__);
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
- lcd->esd_detection_count = 0;
- schedule_delayed_work(&lcd->hs_clk_toggle, HZ/16);
+ lcd->oled_detection_count = 0;
+ schedule_delayed_work(&lcd->oled_detection, HZ/16);
return IRQ_HANDLED;
}
@@ -231,11 +230,11 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
wbuf = seq;
if (size == 1)
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_WR_NO_PARA, wbuf[0], 0);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
else if (size == 2)
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
else
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_LONG_WR, (unsigned int)wbuf, size);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
mutex_unlock(&lcd->lock);
@@ -251,44 +250,14 @@ static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf
mutex_lock(&lcd->lock);
- if (ddi_pd->cmd_read)
- ret = ddi_pd->cmd_read(ddi_pd->dsim_base, addr, count, buf);
+ if (lcd->dsim->ops->cmd_read)
+ ret = lcd->dsim->ops->cmd_read(lcd->dsim, addr, count, buf);
mutex_unlock(&lcd->lock);
return ret;
}
-static int s6e8ax0_set_link(void *pd, unsigned int dsim_base,
- unsigned char (*cmd_write) (unsigned int dsim_base, unsigned int data0,
- unsigned int data1, unsigned int data2),
- int (*cmd_read) (u32 reg_base, u8 addr, u16 count, u8 *buf))
-{
- struct mipi_ddi_platform_data *temp_pd = NULL;
-
- temp_pd = (struct mipi_ddi_platform_data *) pd;
- if (temp_pd == NULL) {
- printk(KERN_ERR "mipi_ddi_platform_data is null.\n");
- return -EPERM;
- }
-
- ddi_pd = temp_pd;
-
- ddi_pd->dsim_base = dsim_base;
-
- if (cmd_write)
- ddi_pd->cmd_write = cmd_write;
- else
- printk(KERN_WARNING "cmd_write function is null.\n");
-
- if (cmd_read)
- ddi_pd->cmd_read = cmd_read;
- else
- printk(KERN_WARNING "cmd_read function is null.\n");
-
- return 0;
-}
-
static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
{
int ret = 0;
@@ -456,7 +425,7 @@ static int s6e8ax0_gamma_ctl(struct lcd_info *lcd)
return 0;
}
-#if defined(CONFIG_MACH_Q1_BD)
+#if defined(CONFIG_S6E8AA0_AMS529HA01)
static int s6e8ax0_set_acl(struct lcd_info *lcd)
{
int ret = 0;
@@ -605,7 +574,7 @@ static int s6e8ax0_set_acl(struct lcd_info *lcd)
#ifdef SMART_DIMMING
#ifdef CONFIG_AID_DIMMING
-static int s6e8ax0_set_elvss(struct lcd_info *lcd)
+static int s6e8ax0_set_elvss(struct lcd_info *lcd, u8 force)
{
int ret = 0, elvss_level = 0;
u32 candela = candela_table[lcd->bl];
@@ -673,7 +642,7 @@ static int s6e8ax0_set_elvss(struct lcd_info *lcd)
break;
}
- if (lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
+ if ((lcd->current_elvss != lcd->elvss_table[elvss_level][2]) || force) {
ret = s6e8ax0_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE);
lcd->current_elvss = lcd->elvss_table[elvss_level][2];
}
@@ -689,7 +658,7 @@ elvss_err:
return ret;
}
#else
-static int s6e8ax0_set_elvss(struct lcd_info *lcd)
+static int s6e8ax0_set_elvss(struct lcd_info *lcd, u8 force)
{
int ret = 0, elvss_level = 0;
u32 candela = candela_table[lcd->bl];
@@ -711,7 +680,7 @@ static int s6e8ax0_set_elvss(struct lcd_info *lcd)
break;
}
- if (lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
+ if ((lcd->current_elvss != lcd->elvss_table[elvss_level][2]) || force) {
ret = s6e8ax0_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE);
lcd->current_elvss = lcd->elvss_table[elvss_level][2];
}
@@ -947,7 +916,7 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
#endif
s6e8ax0_set_acl(lcd);
- s6e8ax0_set_elvss(lcd);
+ s6e8ax0_set_elvss(lcd, force);
lcd->current_bl = lcd->bl;
@@ -963,11 +932,11 @@ static int s6e8ax0_ldi_init(struct lcd_info *lcd)
{
int ret = 0;
-#if defined(CONFIG_MACH_Q1_BD)
+#if defined(CONFIG_S6E8AA0_AMS529HA01)
s6e8ax0_write(lcd, SEQ_APPLY_LEVEL_2_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY));
- msleep(20);
+ s6e8ax0_write(lcd, SEQ_LTPS_DELAY, ARRAY_SIZE(SEQ_LTPS_DELAY));
s6e8ax0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
- usleep_range(5000, 5000);
+ msleep(22);
s6e8ax0_write(lcd, SEQ_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
s6e8ax0_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
s6e8ax0_gamma_ctl(lcd);
@@ -980,7 +949,7 @@ static int s6e8ax0_ldi_init(struct lcd_info *lcd)
s6e8ax0_write(lcd, SEQ_APPLY_LEVEL_2, ARRAY_SIZE(SEQ_APPLY_LEVEL_2));
s6e8ax0_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
s6e8ax0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
- usleep_range(22000, 22000);
+ msleep(22);
/* 4.8" HD for M0/C1*/
if (lcd->id[1] == 0x20 || lcd->id[1] == 0x40 || lcd->id[1] == 0x60) {
@@ -1209,7 +1178,7 @@ static ssize_t lcd_type_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
char temp[15];
-#if defined(CONFIG_MACH_Q1_BD)
+#if defined(CONFIG_S6E8AA0_AMS529HA01)
sprintf(temp, "SMD_AMS529HA01\n");
#else
sprintf(temp, "SMD_AMS480GYXX\n");
@@ -1286,6 +1255,8 @@ void s6e8ax0_early_suspend(void)
{
struct lcd_info *lcd = g_lcd;
+ set_dsim_lcd_enabled(0);
+
dev_info(&lcd->ld->dev, "+%s\n", __func__);
#if defined(GPIO_OLED_DET)
disable_irq(lcd->irq);
@@ -1314,7 +1285,7 @@ void s6e8ax0_late_resume(void)
#endif
dev_info(&lcd->ld->dev, "-%s\n", __func__);
- set_dsim_lcd_enabled();
+ set_dsim_lcd_enabled(1);
return ;
}
@@ -1341,7 +1312,7 @@ static int s6e8ax0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
return ret;
}
-#if defined(CONFIG_MACH_Q1_BD)
+#if defined(CONFIG_S6E8AA0_AMS529HA01)
static void s6e8aa0_check_id(struct lcd_info *lcd, u8 *idbuf)
{
u32 i;
@@ -1409,6 +1380,7 @@ static int s6e8ax0_probe(struct device *dev)
}
lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
lcd->bl = DEFAULT_GAMMA_LEVEL;
@@ -1490,14 +1462,14 @@ static int s6e8ax0_probe(struct device *dev)
#if defined(GPIO_OLED_DET)
if (lcd->connected) {
- INIT_DELAYED_WORK(&lcd->hs_clk_toggle, hs_clk_toggle_work);
+ INIT_DELAYED_WORK(&lcd->oled_detection, oled_detection_work);
lcd->irq = gpio_to_irq(GPIO_OLED_DET);
s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
- if (request_irq(lcd->irq, oled_det_int,
- IRQF_TRIGGER_FALLING, "esd_detection", lcd))
+ if (request_irq(lcd->irq, oled_detection_int,
+ IRQF_TRIGGER_FALLING, "oled_detection", lcd))
pr_err("failed to reqeust irq. %d\n", lcd->irq);
}
#endif
@@ -1540,7 +1512,6 @@ static void s6e8ax0_shutdown(struct device *dev)
static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
.name = "s6e8aa0",
- .set_link = s6e8ax0_set_link,
.probe = s6e8ax0_probe,
.remove = __devexit_p(s6e8ax0_remove),
.shutdown = s6e8ax0_shutdown,
diff --git a/drivers/video/samsung/s3cfb_s6e8ab0.c b/drivers/video/samsung/s3cfb_s6e8ab0.c
index 185bab0..bc47c37 100644
--- a/drivers/video/samsung/s3cfb_s6e8ab0.c
+++ b/drivers/video/samsung/s3cfb_s6e8ab0.c
@@ -101,9 +101,9 @@ struct lcd_info {
struct str_elvss elvss;
#endif
unsigned int connected;
-};
-static struct mipi_ddi_platform_data *ddi_pd;
+ struct dsim_global *dsim;
+};
static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
@@ -119,11 +119,11 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
wbuf = seq;
if (size == 1)
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_WR_NO_PARA, wbuf[0], 0);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
else if (size == 2)
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
else
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_LONG_WR, (unsigned int)wbuf, size);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
mutex_unlock(&lcd->lock);
@@ -139,44 +139,14 @@ static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf
mutex_lock(&lcd->lock);
- if (ddi_pd->cmd_read)
- ret = ddi_pd->cmd_read(ddi_pd->dsim_base, addr, count, buf);
+ if (lcd->dsim->ops->cmd_read)
+ ret = lcd->dsim->ops->cmd_read(lcd->dsim, addr, count, buf);
mutex_unlock(&lcd->lock);
return ret;
}
-static int s6e8ax0_set_link(void *pd, unsigned int dsim_base,
- unsigned char (*cmd_write) (unsigned int dsim_base, unsigned int data0,
- unsigned int data1, unsigned int data2),
- int (*cmd_read) (u32 reg_base, u8 addr, u16 count, u8 *buf))
-{
- struct mipi_ddi_platform_data *temp_pd = NULL;
-
- temp_pd = (struct mipi_ddi_platform_data *) pd;
- if (temp_pd == NULL) {
- printk(KERN_ERR "mipi_ddi_platform_data is null.\n");
- return -EPERM;
- }
-
- ddi_pd = temp_pd;
-
- ddi_pd->dsim_base = dsim_base;
-
- if (cmd_write)
- ddi_pd->cmd_write = cmd_write;
- else
- printk(KERN_WARNING "cmd_write function is null.\n");
-
- if (cmd_read)
- ddi_pd->cmd_read = cmd_read;
- else
- printk(KERN_WARNING "cmd_read function is null.\n");
-
- return 0;
-}
-
static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
{
int ret = 0;
@@ -781,6 +751,8 @@ void s6e8ax0_early_suspend(void)
{
struct lcd_info *lcd = g_lcd;
+ set_dsim_lcd_enabled(0);
+
dev_info(&lcd->ld->dev, "+%s\n", __func__);
s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
@@ -796,7 +768,7 @@ void s6e8ax0_late_resume(void)
s6e8ax0_power(lcd, FB_BLANK_UNBLANK);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
- set_dsim_lcd_enabled();
+ set_dsim_lcd_enabled(1);
return ;
}
@@ -884,6 +856,7 @@ static int s6e8ax0_probe(struct device *dev)
}
lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
lcd->bl = DEFAULT_GAMMA_LEVEL;
@@ -990,7 +963,6 @@ static void s6e8ax0_shutdown(struct device *dev)
static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
.name = "s6e8ab0",
- .set_link = s6e8ax0_set_link,
.probe = s6e8ax0_probe,
.remove = __devexit_p(s6e8ax0_remove),
.shutdown = s6e8ax0_shutdown,
diff --git a/drivers/video/samsung/s5p-dsim.c b/drivers/video/samsung/s5p-dsim.c
index 540a75b..4f2cb7f 100644
--- a/drivers/video/samsung/s5p-dsim.c
+++ b/drivers/video/samsung/s5p-dsim.c
@@ -50,38 +50,6 @@
#include <linux/suspend.h>
#endif
-
-/* Indicates the state of the device */
-struct dsim_global {
- struct device *dev;
- struct clk *clock;
- struct s5p_platform_dsim *pd;
- struct dsim_config *dsim_info;
- struct dsim_lcd_config *dsim_lcd_info;
- /* lcd panel data. */
- struct s3cfb_lcd *lcd_panel_info;
- /* platform and machine specific data for lcd panel driver. */
- struct mipi_ddi_platform_data *mipi_ddi_pd;
- /* lcd panel driver based on MIPI-DSI. */
- struct mipi_lcd_driver *mipi_drv;
-
- unsigned int irq;
- unsigned int te_irq;
- unsigned int reg_base;
- unsigned char state;
- unsigned int data_lane;
- enum dsim_byte_clk_src e_clk_src;
- unsigned long hs_clk;
- unsigned long byte_clk;
- unsigned long escape_clk;
- unsigned char freq_band;
- char header_fifo_index[DSIM_HEADER_FIFO_SZ];
-#ifdef CONFIG_HAS_WAKELOCK
- struct early_suspend early_suspend;
- struct wake_lock idle_lock;
-#endif
-};
-
struct mipi_lcd_info {
struct list_head list;
struct mipi_lcd_driver *mipi_drv;
@@ -134,82 +102,83 @@ static DECLARE_COMPLETION(dsim_wr_comp);
static LIST_HEAD(lcd_info_list);
static DEFINE_MUTEX(mipi_lock);
-static struct dsim_global dsim;
-struct delayed_work dsim_work;
-struct delayed_work check_hs_toggle_work;
+static struct dsim_global *g_dsim;
-static unsigned int dsim_toggle_per_frame_count;
+static struct s5p_platform_dsim *to_dsim_plat(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ return (struct s5p_platform_dsim *)pdev->dev.platform_data;
+}
-void s5p_dsim_frame_done_interrupt_enable(u8 enable)
+static void s5p_dsim_frame_done_interrupt_enable(struct dsim_global *dsim, u8 enable)
{
u32 intmsk;
u8 state = !enable;
- if (!dsim.mipi_ddi_pd->resume_complete)
+ if (!dsim->mipi_ddi_pd->resume_complete)
return;
-#if 0
- if (state == 0) /* enable Frame Done interrupts */
- writel(0xF237FFFF, dsim.reg_base + S5P_DSIM_INTMSK);
- else /* disable Frame Done interrupts */
- writel(0xF337FFFF, dsim.reg_base + S5P_DSIM_INTMSK);
-#else
- intmsk = readl(dsim.reg_base + S5P_DSIM_INTMSK);
+ intmsk = readl(dsim->reg_base + S5P_DSIM_INTMSK);
- if (state == 0)
+ if (state == 0) /* enable Frame Done interrupts */
intmsk &= ~(0x01 << S5P_DSIM_INT_MSK_FRAME_DONE);
- else
+ else /* disable Frame Done interrupts */
intmsk |= (0x01 << S5P_DSIM_INT_MSK_FRAME_DONE);
- writel(intmsk, dsim.reg_base + S5P_DSIM_INTMSK);
-#endif
+ writel(intmsk, dsim->reg_base + S5P_DSIM_INTMSK);
}
-void set_dsim_lcd_enabled(void)
+void set_dsim_lcd_enabled(u8 enable)
{
- dsim.dsim_lcd_info->lcd_enabled = 1;
- if (dsim.dsim_info->hs_toggle)
- s5p_dsim_frame_done_interrupt_enable(1);
+ struct dsim_global *dsim = g_dsim;
+
+ dsim->dsim_lcd_info->lcd_enabled = enable;
+ if (dsim->dsim_info->hs_toggle)
+ s5p_dsim_frame_done_interrupt_enable(dsim, enable);
}
void set_dsim_hs_clk_toggle_count(u8 count)
{
- dsim_toggle_per_frame_count = count;
- if (dsim.dsim_lcd_info->lcd_enabled)
- s5p_dsim_frame_done_interrupt_enable(count ? 1 : 0);
+ struct dsim_global *dsim = g_dsim;
+
+ dsim->dsim_toggle_per_frame_count = count;
+ if (dsim->dsim_lcd_info->lcd_enabled)
+ s5p_dsim_frame_done_interrupt_enable(dsim, count ? 1 : 0);
}
static void dsim_work_q_handler(struct work_struct *work)
{
- s5p_dsim_frame_done_interrupt_enable(1);
-}
+ struct dsim_global *dsim =
+ container_of(work, struct dsim_global, dsim_work.work);
-static void dsim_check_hs_toggle_work_q_handler(struct work_struct *work)
-{
- if (dsim.dsim_info->hs_toggle) {
- dev_info(dsim.dev, "check_hs_toggle.\n");
- schedule_delayed_work(&check_hs_toggle_work,\
- msecs_to_jiffies(120000));
- }
+ s5p_dsim_frame_done_interrupt_enable(dsim, 1);
}
-struct s5p_platform_dsim *to_dsim_plat(struct device *dev)
+static void dsim_check_hs_toggle_work_q_handler(struct work_struct *work)
{
- struct platform_device *pdev = to_platform_device(dev);
+ struct dsim_global *dsim =
+ container_of(work, struct dsim_global, check_hs_toggle_work.work);
- return (struct s5p_platform_dsim *)pdev->dev.platform_data;
+ if (dsim->dsim_info->hs_toggle) {
+ dev_info(dsim->dev, "check_hs_toggle\n");
+ schedule_delayed_work(&dsim->check_hs_toggle_work, msecs_to_jiffies(120000));
+ }
}
-unsigned char s5p_dsim_wr_data(unsigned int dsim_base,
+unsigned char s5p_dsim_wr_data(void *ptr,
unsigned int data_id, unsigned int data0, unsigned int data1)
{
- if (dsim.state == DSIM_STATE_ULPS) {
- dev_err(dsim.dev, "state is ULPS\n");
+ struct dsim_global *dsim = ptr;
+ unsigned int dsim_base = dsim->reg_base;
+
+ if (dsim->state == DSIM_STATE_ULPS) {
+ dev_err(dsim->dev, "DSIM state: ULPS\n");
return DSIM_FALSE;
}
- if (dsim.mipi_ddi_pd->resume_complete == 0) {
- printk(KERN_INFO "DSIM Status: SUSPEND\n");
+ if (dsim->mipi_ddi_pd->resume_complete == 0) {
+ dev_err(dsim->dev, "DSIM Status: SUSPEND\n");
return DSIM_FALSE;
}
@@ -278,7 +247,7 @@ unsigned char s5p_dsim_wr_data(unsigned int dsim_base,
(unsigned char) ((((unsigned short) data1) & 0xff00) >> 8));
if (!wait_for_completion_interruptible_timeout(&dsim_wr_comp, DSIM_TIMEOUT)) {
- printk(KERN_ERR "[DSIM:ERROR] %s Timeout\n", __func__);
+ dev_err(dsim->dev, "[DSIM:ERROR] %s Timeout\n", __func__);
mutex_unlock(&dsim_rd_wr_mutex);
return DSIM_FALSE;
}
@@ -293,13 +262,13 @@ unsigned char s5p_dsim_wr_data(unsigned int dsim_base,
mutex_unlock(&dsim_rd_wr_mutex);
return DSIM_TRUE; /* response should be implemented. */
default:
- dev_warn(dsim.dev, "data id %x is not supported current DSI spec.\n", data_id);
+ dev_warn(dsim->dev, "data id %x is not supported current DSI spec\n", data_id);
mutex_unlock(&dsim_rd_wr_mutex);
return DSIM_FALSE;
}
}
-int s5p_dsim_rd_data(unsigned int reg_base, u8 addr, u16 count, u8 *buf)
+int s5p_dsim_rd_data(void *ptr, u8 addr, u16 count, u8 *buf)
{
u32 i, temp;
u8 response = 0;
@@ -307,11 +276,11 @@ int s5p_dsim_rd_data(unsigned int reg_base, u8 addr, u16 count, u8 *buf)
u32 txhd;
u32 rxhd;
int j;
+ struct dsim_global *dsim = ptr;
+ unsigned int reg_base = dsim->reg_base;
- printk(KERN_INFO "%s called, count : %d\n", __func__, count);
-
- if (dsim.mipi_ddi_pd->resume_complete == 0) {
- printk(KERN_INFO "DSIM Status: SUSPEND\n");
+ if (dsim->mipi_ddi_pd->resume_complete == 0) {
+ dev_err(dsim->dev, "DSIM Status: SUSPEND\n");
return DSIM_FALSE;
}
@@ -341,15 +310,15 @@ int s5p_dsim_rd_data(unsigned int reg_base, u8 addr, u16 count, u8 *buf)
writel(txhd, reg_base + S5P_DSIM_PKTHDR);
if (!wait_for_completion_interruptible_timeout(&dsim_rd_comp, DSIM_TIMEOUT)) {
- printk(KERN_ERR "ERROR:%s timout\n", __func__);
+ dev_err(dsim->dev, "ERROR:%s timout\n", __func__);
mutex_unlock(&dsim_rd_wr_mutex);
return 0;
}
rxhd = readl(reg_base + S5P_DSIM_RXFIFO);
- printk(KERN_INFO "rxhd : %x\n", rxhd);
+ dev_info(dsim->dev, "rxhd : %x\n", rxhd);
if ((u8)(rxhd & 0xff) != response) {
- printk(KERN_ERR "[DSIM:ERROR]:%s wrong response rxhd : %x, response:%x\n"
+ dev_err(dsim->dev, "[DSIM:ERROR]:%s wrong response rxhd : %x, response:%x\n"
, __func__, rxhd, response);
goto clear_rx_fifo;
}
@@ -361,16 +330,16 @@ int s5p_dsim_rd_data(unsigned int reg_base, u8 addr, u16 count, u8 *buf)
} else {
/* for long packet */
rxsize = (u16)((rxhd & 0x00ffff00) >> 8);
- printk(KERN_INFO "rcv size : %d\n", rxsize);
+ dev_info(dsim->dev, "rcv size : %d\n", rxsize);
if (rxsize != count) {
- printk(KERN_ERR "[DSIM:ERROR]:%s received data size mismatch received : %d, requested : %d\n",
+ dev_err(dsim->dev, "[DSIM:ERROR]:%s received data size mismatch received : %d, requested : %d\n",
__func__, rxsize, count);
goto clear_rx_fifo;
}
for (i = 0; i < rxsize>>2; i++) {
temp = readl(reg_base + S5P_DSIM_RXFIFO);
- printk(KERN_INFO "pkt : %08x\n", temp);
+ dev_info(dsim->dev, "pkt : %08x\n", temp);
for (j = 0; j < 4; j++) {
buf[(i*4)+j] = (u8)(temp>>(j*8))&0xff;
/* printk("Value : %02x\n",(temp>>(j*8))&0xff); */
@@ -378,7 +347,7 @@ int s5p_dsim_rd_data(unsigned int reg_base, u8 addr, u16 count, u8 *buf)
}
if (rxsize % 4) {
temp = readl(reg_base + S5P_DSIM_RXFIFO);
- printk(KERN_INFO "pkt-l : %08x\n", temp);
+ dev_info(dsim->dev, "pkt-l : %08x\n", temp);
for (j = 0; j < rxsize%4; j++) {
buf[(i*4)+j] = (u8)(temp>>(j*8))&0xff;
/* printk("Value : %02x\n",(temp>>(j*8))&0xff); */
@@ -389,7 +358,7 @@ int s5p_dsim_rd_data(unsigned int reg_base, u8 addr, u16 count, u8 *buf)
temp = readl(reg_base + S5P_DSIM_RXFIFO);
if (temp != DSIM_RX_FIFO_READ_DONE) {
- printk(KERN_WARNING "[DSIM:WARN]:%s Can't found RX FIFO READ DONE FLAG : %x\n", __func__, temp);
+ dev_warn(dsim->dev, "[DSIM:WARN]:%s Can't found RX FIFO READ DONE FLAG : %x\n", __func__, temp);
goto clear_rx_fifo;
}
@@ -402,10 +371,10 @@ clear_rx_fifo:
temp = readl(reg_base+S5P_DSIM_RXFIFO);
if ((temp == DSIM_RX_FIFO_READ_DONE) || (i > DSIM_MAX_RX_FIFO))
break;
- printk(KERN_INFO "[DSIM:INFO] : %s clear rx fifo : %08x\n", __func__, temp);
+ dev_info(dsim->dev, "[DSIM:INFO] : %s clear rx fifo : %08x\n", __func__, temp);
i++;
}
- printk(KERN_INFO "[DSIM:INFO] : %s done count : %d, temp : %08x\n", __func__, i, temp);
+ dev_info(dsim->dev, "[DSIM:INFO] : %s done count : %d, temp : %08x\n", __func__, i, temp);
mutex_unlock(&dsim_rd_wr_mutex);
return 0;
@@ -417,16 +386,16 @@ static irqreturn_t s5p_dsim_isr(int irq, void *dev_id)
int i;
unsigned int intsrc = 0;
unsigned int intmsk = 0;
- struct dsim_global *pdsim = NULL;
+ struct dsim_global *dsim = NULL;
- pdsim = (struct dsim_global *)dev_id;
- if (!pdsim) {
+ dsim = (struct dsim_global *)dev_id;
+ if (!dsim) {
printk(KERN_ERR "%s:error:wrong parameter\n", __func__);
return IRQ_HANDLED;
}
- intsrc = readl(pdsim->reg_base + S5P_DSIM_INTSRC);
- intmsk = readl(pdsim->reg_base + S5P_DSIM_INTMSK);
+ intsrc = readl(dsim->reg_base + S5P_DSIM_INTSRC);
+ intmsk = readl(dsim->reg_base + S5P_DSIM_INTMSK);
intmsk = ~(intmsk) & intsrc;
@@ -464,16 +433,18 @@ static irqreturn_t s5p_dsim_isr(int irq, void *dev_id)
break;
case S5P_DSIM_INT_MSK_FRAME_DONE:
/* printk("S5P_DSIM_INT_MSK_FRAME_DONE\n"); */
- if (s3cfb_vsync_status_check() && dsim.mipi_ddi_pd->resume_complete == 1) {
+ if (dsim->dsim_lcd_info->lcd_enabled && dsim->mipi_ddi_pd->resume_complete) {
if (completion_done(&dsim_wr_comp) && completion_done(&dsim_rd_comp)) {
- s5p_dsim_toggle_hs_clock(dsim.reg_base);
- if (!dsim_toggle_per_frame_count) {
- s5p_dsim_frame_done_interrupt_enable(0);
- if (likely(dsim.dsim_info->hs_toggle - 1))
- schedule_delayed_work(&dsim_work, dsim.dsim_info->hs_toggle);
+ if (s3cfb_vsync_status_check()) {
+ s5p_dsim_toggle_hs_clock(dsim->reg_base);
+ if (!dsim->dsim_toggle_per_frame_count) {
+ s5p_dsim_frame_done_interrupt_enable(dsim, 0);
+ if (likely(dsim->dsim_info->hs_toggle - 1))
+ schedule_delayed_work(&dsim->dsim_work, dsim->dsim_info->hs_toggle);
+ }
+ if (dsim->dsim_toggle_per_frame_count)
+ dsim->dsim_toggle_per_frame_count--;
}
- if (dsim_toggle_per_frame_count)
- dsim_toggle_per_frame_count--;
}
}
break;
@@ -481,20 +452,20 @@ static irqreturn_t s5p_dsim_isr(int irq, void *dev_id)
}
}
/* clear irq */
- writel(intsrc, pdsim->reg_base + S5P_DSIM_INTSRC);
+ writel(intsrc, dsim->reg_base + S5P_DSIM_INTSRC);
return IRQ_HANDLED;
}
-static void s5p_dsim_init_header_fifo(void)
+static void s5p_dsim_init_header_fifo(struct dsim_global *dsim)
{
unsigned int cnt;
for (cnt = 0; cnt < DSIM_HEADER_FIFO_SZ; cnt++)
- dsim.header_fifo_index[cnt] = -1;
+ dsim->header_fifo_index[cnt] = -1;
return;
}
-unsigned char s5p_dsim_pll_on(unsigned int dsim_base, unsigned char enable)
+static unsigned char s5p_dsim_pll_on(unsigned int dsim_base, unsigned char enable)
{
if (enable) {
int sw_timeout = 1000;
@@ -513,19 +484,20 @@ unsigned char s5p_dsim_pll_on(unsigned int dsim_base, unsigned char enable)
return DSIM_TRUE;
}
-static unsigned long s5p_dsim_change_pll(unsigned int dsim_base, unsigned char pre_divider,
+static unsigned long s5p_dsim_change_pll(struct dsim_global *dsim, unsigned char pre_divider,
unsigned short main_divider, unsigned char scaler)
{
unsigned long dfin_pll, dfvco, dpll_out;
unsigned char freq_band;
unsigned char temp0 = 0, temp1 = 0;
+ unsigned int dsim_base = dsim->reg_base;
dfin_pll = (MIPI_FIN / pre_divider);
if (dfin_pll < 6 * 1000 * 1000 || dfin_pll > 12 * 1000 * 1000) {
- dev_warn(dsim.dev, "warning!!\n");
- dev_warn(dsim.dev, "fin_pll range is 6MHz ~ 12MHz\n");
- dev_warn(dsim.dev, "fin_pll of mipi dphy pll is %luMHz\n", (dfin_pll / 1000000));
+ dev_warn(dsim->dev, "warning!!\n");
+ dev_warn(dsim->dev, "fin_pll range is 6MHz ~ 12MHz\n");
+ dev_warn(dsim->dev, "fin_pll of mipi dphy pll is %luMHz\n", (dfin_pll / 1000000));
s5p_dsim_enable_afc(dsim_base, 0, 0);
} else {
@@ -544,16 +516,16 @@ static unsigned long s5p_dsim_change_pll(unsigned int dsim_base, unsigned char p
}
dfvco = dfin_pll * main_divider;
- dev_dbg(dsim.dev, "dfvco = %lu, dfin_pll = %lu, main_divider = %d\n",
+ dev_dbg(dsim->dev, "dfvco = %lu, dfin_pll = %lu, main_divider = %d\n",
dfvco, dfin_pll, main_divider);
if (dfvco < 500000000 || dfvco > 1000000000) {
- dev_warn(dsim.dev, "Caution!!\n");
- dev_warn(dsim.dev, "fvco range is 500MHz ~ 1000MHz\n");
- dev_warn(dsim.dev, "fvco of mipi dphy pll is %luMHz\n", (dfvco / 1000000));
+ dev_warn(dsim->dev, "Caution!!\n");
+ dev_warn(dsim->dev, "fvco range is 500MHz ~ 1000MHz\n");
+ dev_warn(dsim->dev, "fvco of mipi dphy pll is %luMHz\n", (dfvco / 1000000));
}
dpll_out = dfvco / (1 << scaler);
- dev_dbg(dsim.dev, "dpll_out = %lu, dfvco = %lu, scaler = %d\n",
+ dev_dbg(dsim->dev, "dpll_out = %lu, dfvco = %lu, scaler = %d\n",
dpll_out, dfvco, scaler);
if (dpll_out < 100 * 1000000)
freq_band = 0x0;
@@ -588,7 +560,7 @@ static unsigned long s5p_dsim_change_pll(unsigned int dsim_base, unsigned char p
else
freq_band = 0xf;
- dev_dbg(dsim.dev, "freq_band = %d\n", freq_band);
+ dev_dbg(dsim->dev, "freq_band = %d\n", freq_band);
s5p_dsim_pll_freq(dsim_base, pre_divider, main_divider, scaler);
@@ -599,51 +571,52 @@ static unsigned long s5p_dsim_change_pll(unsigned int dsim_base, unsigned char p
s5p_dsim_pll_freq_band(dsim_base, freq_band);
/* Stable time */
- s5p_dsim_pll_stable_time(dsim_base, dsim.dsim_info->pll_stable_time);
+ s5p_dsim_pll_stable_time(dsim_base, dsim->dsim_info->pll_stable_time);
/* Enable PLL */
- dev_dbg(dsim.dev, "FOUT of mipi dphy pll is %luMHz\n", (dpll_out / 1000000));
+ dev_dbg(dsim->dev, "FOUT of mipi dphy pll is %luMHz\n", (dpll_out / 1000000));
return dpll_out;
}
-static void s5p_dsim_set_clock(unsigned int dsim_base,
+static void s5p_dsim_set_clock(struct dsim_global *dsim,
unsigned char byte_clk_sel, unsigned char enable)
{
unsigned int esc_div;
unsigned long esc_clk_error_rate;
+ unsigned int dsim_base = dsim->reg_base;
if (enable) {
- dsim.e_clk_src = byte_clk_sel;
+ dsim->e_clk_src = byte_clk_sel;
/* Escape mode clock and byte clock source */
s5p_dsim_set_byte_clock_src(dsim_base, byte_clk_sel);
/* DPHY, DSIM Link : D-PHY clock out */
if (byte_clk_sel == DSIM_PLL_OUT_DIV8) {
- dsim.hs_clk = s5p_dsim_change_pll(dsim_base, dsim.dsim_info->p,
- dsim.dsim_info->m, dsim.dsim_info->s);
- dsim.byte_clk = dsim.hs_clk / 8;
+ dsim->hs_clk = s5p_dsim_change_pll(dsim, dsim->dsim_info->p,
+ dsim->dsim_info->m, dsim->dsim_info->s);
+ dsim->byte_clk = dsim->hs_clk / 8;
s5p_dsim_enable_pll_bypass(dsim_base, 0);
s5p_dsim_pll_on(dsim_base, 1);
usleep_range(1000, 1000);
/* DPHY : D-PHY clock out, DSIM link : external clock out */
} else if (byte_clk_sel == DSIM_EXT_CLK_DIV8)
- dev_warn(dsim.dev, "this project is not supported external clock source for MIPI DSIM\n");
+ dev_warn(dsim->dev, "this project is not supported external clock source for MIPI DSIM\n");
else if (byte_clk_sel == DSIM_EXT_CLK_BYPASS)
- dev_warn(dsim.dev, "this project is not supported external clock source for MIPI DSIM\n");
+ dev_warn(dsim->dev, "this project is not supported external clock source for MIPI DSIM\n");
/* escape clock divider */
- esc_div = dsim.byte_clk / (dsim.dsim_info->esc_clk);
- dev_dbg(dsim.dev, "esc_div = %d, byte_clk = %lu, esc_clk = %lu\n",
- esc_div, dsim.byte_clk, dsim.dsim_info->esc_clk);
- if ((dsim.byte_clk / esc_div) >= 20000000 ||
- (dsim.byte_clk / esc_div) > dsim.dsim_info->esc_clk)
+ esc_div = dsim->byte_clk / (dsim->dsim_info->esc_clk);
+ dev_dbg(dsim->dev, "esc_div = %d, byte_clk = %lu, esc_clk = %lu\n",
+ esc_div, dsim->byte_clk, dsim->dsim_info->esc_clk);
+ if ((dsim->byte_clk / esc_div) >= 20000000 ||
+ (dsim->byte_clk / esc_div) > dsim->dsim_info->esc_clk)
esc_div += 1;
- dsim.escape_clk = dsim.byte_clk / esc_div;
- dev_dbg(dsim.dev, "escape_clk = %lu, byte_clk = %lu, esc_div = %d\n",
- dsim.escape_clk, dsim.byte_clk, esc_div);
+ dsim->escape_clk = dsim->byte_clk / esc_div;
+ dev_dbg(dsim->dev, "escape_clk = %lu, byte_clk = %lu, esc_div = %d\n",
+ dsim->escape_clk, dsim->byte_clk, esc_div);
/*
* enable escclk on lane
@@ -653,22 +626,22 @@ static void s5p_dsim_set_clock(unsigned int dsim_base,
/* enable byte clk and escape clock */
s5p_dsim_set_esc_clk_prs(dsim_base, 1, esc_div);
/* escape clock on lane */
- s5p_dsim_enable_esc_clk_on_lane(dsim_base, (DSIM_LANE_CLOCK | dsim.data_lane), 1);
-
- dev_dbg(dsim.dev, "byte clock is %luMHz\n", (dsim.byte_clk / 1000000));
- dev_dbg(dsim.dev, "escape clock that user's need is %lu\n", (dsim.dsim_info->esc_clk / 1000000));
- dev_dbg(dsim.dev, "escape clock divider is %x\n", esc_div);
- dev_dbg(dsim.dev, "escape clock is %luMHz\n", ((dsim.byte_clk / esc_div) / 1000000));
-
- if ((dsim.byte_clk / esc_div) > dsim.escape_clk) {
- esc_clk_error_rate = dsim.escape_clk / (dsim.byte_clk / esc_div);
- dev_warn(dsim.dev, "error rate is %lu over.\n", (esc_clk_error_rate / 100));
- } else if ((dsim.byte_clk / esc_div) < (dsim.escape_clk)) {
- esc_clk_error_rate = (dsim.byte_clk / esc_div) / dsim.escape_clk;
- dev_warn(dsim.dev, "error rate is %lu under.\n", (esc_clk_error_rate / 100));
+ s5p_dsim_enable_esc_clk_on_lane(dsim_base, (DSIM_LANE_CLOCK | dsim->data_lane), 1);
+
+ dev_dbg(dsim->dev, "byte clock is %luMHz\n", (dsim->byte_clk / 1000000));
+ dev_dbg(dsim->dev, "escape clock that user's need is %lu\n", (dsim->dsim_info->esc_clk / 1000000));
+ dev_dbg(dsim->dev, "escape clock divider is %x\n", esc_div);
+ dev_dbg(dsim->dev, "escape clock is %luMHz\n", ((dsim->byte_clk / esc_div) / 1000000));
+
+ if ((dsim->byte_clk / esc_div) > dsim->escape_clk) {
+ esc_clk_error_rate = dsim->escape_clk / (dsim->byte_clk / esc_div);
+ dev_warn(dsim->dev, "error rate is %lu over\n", (esc_clk_error_rate / 100));
+ } else if ((dsim->byte_clk / esc_div) < (dsim->escape_clk)) {
+ esc_clk_error_rate = (dsim->byte_clk / esc_div) / dsim->escape_clk;
+ dev_warn(dsim->dev, "error rate is %lu under\n", (esc_clk_error_rate / 100));
}
} else {
- s5p_dsim_enable_esc_clk_on_lane(dsim_base, (DSIM_LANE_CLOCK | dsim.data_lane), 0);
+ s5p_dsim_enable_esc_clk_on_lane(dsim_base, (DSIM_LANE_CLOCK | dsim->data_lane), 0);
s5p_dsim_set_esc_clk_prs(dsim_base, 0, 0);
s5p_dsim_enable_byte_clock(dsim_base, DSIM_FALSE);
@@ -678,88 +651,93 @@ static void s5p_dsim_set_clock(unsigned int dsim_base,
}
}
-static int s5p_dsim_late_resume_init_dsim(unsigned int dsim_base)
+static int s5p_dsim_late_resume_init_dsim(struct dsim_global *dsim)
{
- if (dsim.pd->init_d_phy)
- dsim.pd->init_d_phy(dsim.reg_base);
+ unsigned int dsim_base = dsim->reg_base;
- dsim.state = DSIM_STATE_RESET;
+ if (dsim->pd->init_d_phy)
+ dsim->pd->init_d_phy(dsim->reg_base);
- switch (dsim.dsim_info->e_no_data_lane) {
+ dsim->state = DSIM_STATE_RESET;
+
+ switch (dsim->dsim_info->e_no_data_lane) {
case DSIM_DATA_LANE_1:
- dsim.data_lane = DSIM_LANE_DATA0;
+ dsim->data_lane = DSIM_LANE_DATA0;
break;
case DSIM_DATA_LANE_2:
- dsim.data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1;
+ dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1;
break;
case DSIM_DATA_LANE_3:
- dsim.data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
+ dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
DSIM_LANE_DATA2;
break;
case DSIM_DATA_LANE_4:
- dsim.data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
+ dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
DSIM_LANE_DATA2 | DSIM_LANE_DATA3;
break;
default:
- dev_info(dsim.dev, "data lane is invalid.\n");
+ dev_info(dsim->dev, "data lane is invalid\n");
return -1;
};
- s5p_dsim_init_header_fifo();
+ s5p_dsim_init_header_fifo(dsim);
s5p_dsim_sw_reset(dsim_base);
- s5p_dsim_dp_dn_swap(dsim_base, dsim.dsim_info->e_lane_swap);
+ s5p_dsim_dp_dn_swap(dsim_base, dsim->dsim_info->e_lane_swap);
/* enable only frame done interrupt */
/* s5p_dsim_clear_interrupt(dsim_base, AllDsimIntr); */
- /* s5p_dsim_set_interrupt_mask(dsim.reg_base, AllDsimIntr, 1); */
+ /* s5p_dsim_set_interrupt_mask(dsim->reg_base, AllDsimIntr, 1); */
return 0;
}
#if 0
-static int s5p_dsim_init_dsim(unsigned int dsim_base)
+static int s5p_dsim_init_dsim(struct dsim_global *dsim)
{
- if (dsim.pd->init_d_phy)
- dsim.pd->init_d_phy(dsim.reg_base);
+ unsigned int dsim_base = dsim->reg_base;
+
+ if (dsim->pd->init_d_phy)
+ dsim->pd->init_d_phy(dsim->reg_base);
- dsim.state = DSIM_STATE_RESET;
+ dsim->state = DSIM_STATE_RESET;
- switch (dsim.dsim_info->e_no_data_lane) {
+ switch (dsim->dsim_info->e_no_data_lane) {
case DSIM_DATA_LANE_1:
- dsim.data_lane = DSIM_LANE_DATA0;
+ dsim->data_lane = DSIM_LANE_DATA0;
break;
case DSIM_DATA_LANE_2:
- dsim.data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1;
+ dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1;
break;
case DSIM_DATA_LANE_3:
- dsim.data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
+ dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
DSIM_LANE_DATA2;
break;
case DSIM_DATA_LANE_4:
- dsim.data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
+ dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
DSIM_LANE_DATA2 | DSIM_LANE_DATA3;
break;
default:
- dev_info(dsim.dev, "data lane is invalid.\n");
+ dev_info(dsim->dev, "data lane is invalid\n");
return -1;
};
- s5p_dsim_init_header_fifo();
- s5p_dsim_dp_dn_swap(dsim_base, dsim.dsim_info->e_lane_swap);
+ s5p_dsim_init_header_fifo(dsim);
+ s5p_dsim_dp_dn_swap(dsim_base, dsim->dsim_info->e_lane_swap);
/* enable only frame done interrupt */
/* s5p_dsim_clear_interrupt(dsim_base, AllDsimIntr); */
- /* s5p_dsim_set_interrupt_mask(dsim.reg_base, AllDsimIntr, 1); */
+ /* s5p_dsim_set_interrupt_mask(dsim->reg_base, AllDsimIntr, 1); */
return 0;
}
#endif
-static void s5p_dsim_set_display_mode(unsigned int dsim_base,
+static void s5p_dsim_set_display_mode(struct dsim_global *dsim,
struct dsim_lcd_config *main_lcd, struct dsim_lcd_config *sub_lcd)
{
struct s3cfb_lcd *main_lcd_panel_info = NULL, *sub_lcd_panel_info = NULL;
struct s3cfb_lcd_timing *main_timing = NULL;
+ unsigned int dsim_base = dsim->reg_base;
if (main_lcd != NULL) {
if (main_lcd->lcd_panel_info != NULL) {
@@ -770,18 +748,18 @@ static void s5p_dsim_set_display_mode(unsigned int dsim_base,
main_lcd_panel_info->height,
main_lcd_panel_info->width);
} else
- dev_warn(dsim.dev, "lcd panel info of main lcd is NULL.\n");
+ dev_warn(dsim->dev, "lcd panel info of main lcd is NULL\n");
} else {
- dev_err(dsim.dev, "main lcd is NULL.\n");
+ dev_err(dsim->dev, "main lcd is NULL\n");
return;
}
/* in case of VIDEO MODE (RGB INTERFACE) */
- if (dsim.dsim_lcd_info->e_interface == (u32) DSIM_VIDEO) {
+ if (dsim->dsim_lcd_info->e_interface == (u32)DSIM_VIDEO) {
main_timing = &main_lcd_panel_info->timing;
if (main_timing == NULL) {
- dev_err(dsim.dev, "main_timing is NULL.\n");
+ dev_err(dsim->dev, "main_timing is NULL\n");
return;
}
@@ -805,130 +783,131 @@ static void s5p_dsim_set_display_mode(unsigned int dsim_base,
sub_lcd_panel_info->height,
sub_lcd_panel_info->width);
} else
- dev_warn(dsim.dev, "lcd panel info of sub lcd is NULL.\n");
+ dev_warn(dsim->dev, "lcd panel info of sub lcd is NULL\n");
}
}
- s5p_dsim_display_config(dsim_base, dsim.dsim_lcd_info, NULL);
+ s5p_dsim_display_config(dsim_base, dsim->dsim_lcd_info, NULL);
}
-static int s5p_dsim_init_link(unsigned int dsim_base)
+static int s5p_dsim_init_link(struct dsim_global *dsim)
{
unsigned int time_out = 100;
+ unsigned int dsim_base = dsim->reg_base;
- switch (dsim.state) {
+ switch (dsim->state) {
case DSIM_STATE_RESET:
case DSIM_STATE_INIT:
- printk(KERN_INFO "%s\n", __func__);
s5p_dsim_init_fifo_pointer(dsim_base, 0x0);
usleep_range(10000, 10000);
s5p_dsim_init_fifo_pointer(dsim_base, 0x1f);
/* dsi configuration */
- s5p_dsim_init_config(dsim_base, dsim.dsim_lcd_info, NULL, dsim.dsim_info);
+ s5p_dsim_init_config(dsim_base, dsim->dsim_lcd_info, NULL, dsim->dsim_info);
s5p_dsim_enable_lane(dsim_base, DSIM_LANE_CLOCK, 1);
- s5p_dsim_enable_lane(dsim_base, dsim.data_lane, 1);
+ s5p_dsim_enable_lane(dsim_base, dsim->data_lane, 1);
/* set clock configuration */
- s5p_dsim_set_clock(dsim_base, dsim.dsim_info->e_byte_clk, 1);
+ s5p_dsim_set_clock(dsim, dsim->dsim_info->e_byte_clk, 1);
usleep_range(5000, 5000);
/* check clock and data lane state is stop state */
while (!(s5p_dsim_is_lane_state(dsim_base, DSIM_LANE_CLOCK) == DSIM_LANE_STATE_STOP) &&
- !(s5p_dsim_is_lane_state(dsim_base, dsim.data_lane) == DSIM_LANE_STATE_STOP)) {
+ !(s5p_dsim_is_lane_state(dsim_base, dsim->data_lane) == DSIM_LANE_STATE_STOP)) {
time_out--;
if (time_out == 0) {
- dev_info(dsim.dev, "DSI Master state is not stop state!!!\n");
- dev_info(dsim.dev, "Please check initialization process\n");
+ dev_info(dsim->dev, "DSI Master state is not stop state!!!\n");
+ dev_info(dsim->dev, "Please check initialization process\n");
return DSIM_FALSE;
}
}
if (time_out != 0) {
- /* dev_info(dsim.dev, "initialization of DSI Master is successful\n"); */
- /* dev_info(dsim.dev, "DSI Master state is stop state\n"); */
+ /* dev_info(dsim->dev, "initialization of DSI Master is successful\n"); */
+ /* dev_info(dsim->dev, "DSI Master state is stop state\n"); */
}
- dsim.state = DSIM_STATE_STOP;
+ dsim->state = DSIM_STATE_STOP;
/* BTA sequence counters */
- s5p_dsim_set_stop_state_counter(dsim_base, dsim.dsim_info->stop_holding_cnt);
- s5p_dsim_set_bta_timeout(dsim_base, dsim.dsim_info->bta_timeout);
- s5p_dsim_set_lpdr_timeout(dsim_base, dsim.dsim_info->rx_timeout);
+ s5p_dsim_set_stop_state_counter(dsim_base, dsim->dsim_info->stop_holding_cnt);
+ s5p_dsim_set_bta_timeout(dsim_base, dsim->dsim_info->bta_timeout);
+ s5p_dsim_set_lpdr_timeout(dsim_base, dsim->dsim_info->rx_timeout);
/* default LPDT by both cpu and lcd controller */
- s5p_dsim_set_data_mode(dsim_base, DSIM_TRANSFER_BOTH,
- DSIM_STATE_STOP);
+ s5p_dsim_set_data_mode(dsim_base, DSIM_TRANSFER_BOTH, DSIM_STATE_STOP);
return DSIM_TRUE;
default:
- dev_info(dsim.dev, "DSI Master is already init.\n");
+ dev_info(dsim->dev, "DSI Master is already init\n");
return DSIM_FALSE;
}
}
-unsigned char s5p_dsim_set_hs_enable(unsigned int dsim_base)
+static unsigned char s5p_dsim_set_hs_enable(struct dsim_global *dsim)
{
u8 ret = DSIM_FALSE;
+ unsigned int dsim_base = dsim->reg_base;
- if (dsim.state == DSIM_STATE_STOP) {
- if (dsim.e_clk_src != DSIM_EXT_CLK_BYPASS) {
- dsim.state = DSIM_STATE_HSCLKEN;
- s5p_dsim_set_data_mode(dsim_base, DSIM_TRANSFER_BOTH,
- DSIM_STATE_HSCLKEN);
+ if (dsim->state == DSIM_STATE_STOP) {
+ if (dsim->e_clk_src != DSIM_EXT_CLK_BYPASS) {
+ dsim->state = DSIM_STATE_HSCLKEN;
+ s5p_dsim_set_data_mode(dsim_base, DSIM_TRANSFER_BOTH, DSIM_STATE_HSCLKEN);
s5p_dsim_enable_hs_clock(dsim_base, 1);
ret = DSIM_TRUE;
} else
- dev_warn(dsim.dev, "clock source is external bypass.\n");
+ dev_warn(dsim->dev, "clock source is external bypass\n");
} else
- dev_warn(dsim.dev, "DSIM is not stop state.\n");
+ dev_warn(dsim->dev, "DSIM is not stop state\n");
return ret;
}
#if 0
-static unsigned char s5p_dsim_set_stopstate(unsigned int dsim_base)
+static unsigned char s5p_dsim_set_stopstate(struct dsim_global *dsim)
{
u8 ret = DSIM_FALSE;
+ unsigned int dsim_base = dsim->reg_base;
- if (dsim.state == DSIM_STATE_HSCLKEN) {
- if (dsim.e_clk_src != DSIM_EXT_CLK_BYPASS) {
- dsim.state = DSIM_STATE_STOP;
+ if (dsim->state == DSIM_STATE_HSCLKEN) {
+ if (dsim->e_clk_src != DSIM_EXT_CLK_BYPASS) {
+ dsim->state = DSIM_STATE_STOP;
s5p_dsim_enable_hs_clock(dsim_base, 0);
ret = DSIM_TRUE;
} else
- dev_warn(dsim.dev, "clock source is external bypass.\n");
- } else if (dsim.state == DSIM_STATE_ULPS) {
+ dev_warn(dsim->dev, "clock source is external bypass\n");
+ } else if (dsim->state == DSIM_STATE_ULPS) {
/* will be update for exiting ulps */
ret = DSIM_TRUE;
- } else if (dsim.state == DSIM_STATE_STOP) {
- dev_warn(dsim.dev, "DSIM is already stop state.\n");
+ } else if (dsim->state == DSIM_STATE_STOP) {
+ dev_warn(dsim->dev, "DSIM is already stop state\n");
ret = DSIM_TRUE;
} else
- dev_warn(dsim.dev, "DSIM is not stop state.\n");
+ dev_warn(dsim->dev, "DSIM is not stop state\n");
return ret;
}
#endif
-static unsigned char s5p_dsim_set_data_transfer_mode(unsigned int dsim_base,
+static unsigned char s5p_dsim_set_data_transfer_mode(struct dsim_global *dsim,
unsigned char data_path, unsigned char hs_enable)
{
u8 ret = DSIM_FALSE;
+ unsigned int dsim_base = dsim->reg_base;
if (hs_enable) {
- if (dsim.state == DSIM_STATE_HSCLKEN) {
+ if (dsim->state == DSIM_STATE_HSCLKEN) {
s5p_dsim_set_data_mode(dsim_base, data_path, DSIM_STATE_HSCLKEN);
ret = DSIM_TRUE;
} else {
- dev_err(dsim.dev, "HS Clock lane is not enabled.\n");
+ dev_err(dsim->dev, "HS Clock lane is not enabled\n");
ret = DSIM_FALSE;
}
} else {
- if (dsim.state == DSIM_STATE_INIT || dsim.state == DSIM_STATE_ULPS) {
- dev_err(dsim.dev, "DSI Master is not STOP or HSDT state.\n");
+ if (dsim->state == DSIM_STATE_INIT || dsim->state == DSIM_STATE_ULPS) {
+ dev_err(dsim->dev, "DSI Master is not STOP or HSDT state\n");
ret = DSIM_FALSE;
} else {
s5p_dsim_set_data_mode(dsim_base, data_path, DSIM_STATE_STOP);
@@ -941,7 +920,8 @@ static unsigned char s5p_dsim_set_data_transfer_mode(unsigned int dsim_base,
int s5p_dsim_register_lcd_driver(struct mipi_lcd_driver *lcd_drv)
{
- struct mipi_lcd_info *lcd_info = NULL;
+ struct mipi_lcd_info *lcd_info = NULL;
+ struct dsim_global *dsim = g_dsim;
lcd_info = kmalloc(sizeof(struct mipi_lcd_info), GFP_KERNEL);
if (lcd_info == NULL)
@@ -959,45 +939,42 @@ int s5p_dsim_register_lcd_driver(struct mipi_lcd_driver *lcd_drv)
list_add_tail(&lcd_info->list, &lcd_info_list);
mutex_unlock(&mipi_lock);
- dev_dbg(dsim.dev, "registered lcd panel driver(%s) to mipi-dsi driver.\n",
- lcd_drv->name);
+ dev_dbg(dsim->dev, "registered lcd panel driver(%s) to mipi-dsi driver\n", lcd_drv->name);
return 0;
}
-struct mipi_lcd_driver *scan_mipi_driver(const char *name)
+static struct mipi_lcd_driver *scan_mipi_driver(struct dsim_global *dsim, const char *name)
{
struct mipi_lcd_info *lcd_info;
struct mipi_lcd_driver *mipi_drv = NULL;
mutex_lock(&mipi_lock);
- dev_dbg(dsim.dev, "find lcd panel driver(%s).\n",
- name);
+ dev_dbg(dsim->dev, "find lcd panel driver(%s)\n", name);
list_for_each_entry(lcd_info, &lcd_info_list, list) {
mipi_drv = lcd_info->mipi_drv;
if ((strcmp(mipi_drv->name, name)) == 0) {
mutex_unlock(&mipi_lock);
- dev_dbg(dsim.dev, "found!!!(%s).\n", mipi_drv->name);
+ dev_dbg(dsim->dev, "found!!!(%s)\n", mipi_drv->name);
return mipi_drv;
}
}
- dev_warn(dsim.dev, "failed to find lcd panel driver(%s).\n",
- name);
+ dev_warn(dsim->dev, "failed to find lcd panel driver(%s)\n", name);
mutex_unlock(&mipi_lock);
return NULL;
}
-void s5p_dsim_interrupt_mask_set(void)
+static void s5p_dsim_interrupt_mask_set(struct dsim_global *dsim)
{
u32 int_stat;
- int_stat = readl(dsim.reg_base + S5P_DSIM_INTMSK);
+ int_stat = readl(dsim->reg_base + S5P_DSIM_INTMSK);
int_stat &= ~((0x01<<S5P_DSIM_INT_BTA) | (0x01<<S5P_DSIM_INT_RX_TIMEOUT) |
(0x01<<S5P_DSIM_INT_BTA_TIMEOUT) | (0x01 << S5P_DSIM_INT_RX_DONE) |
@@ -1005,26 +982,27 @@ void s5p_dsim_interrupt_mask_set(void)
(0x01<<S5P_DSIM_INT_RX_ECC_ERR) | (0x01<<S5P_DSIM_IMT_RX_CRC_ERR) |
(0x01<<S5P_DSIM_INT_SFR_FIFO_EMPTY));
- writel(int_stat, dsim.reg_base + S5P_DSIM_INTMSK);
+ writel(int_stat, dsim->reg_base + S5P_DSIM_INTMSK);
}
int s5p_dsim_fifo_clear(void)
{
int dsim_count = 0, ret;
+ struct dsim_global *dsim = g_dsim;
- writel(SwRstRelease, dsim.reg_base + S5P_DSIM_INTSRC);
+ writel(SwRstRelease, dsim->reg_base + S5P_DSIM_INTSRC);
- writel(DSIM_FUNCRST, dsim.reg_base + S5P_DSIM_SWRST);
+ writel(DSIM_FUNCRST, dsim->reg_base + S5P_DSIM_SWRST);
do {
if (++dsim_count > 90000) {
- printk(KERN_ERR "dsim fifo clear fail re_try dsim resume\n");
+ dev_err(dsim->dev, "dsim fifo clear fail re_try dsim resume\n");
ret = 0;
break;
}
- if (readl(dsim.reg_base + S5P_DSIM_INTSRC) & SwRstRelease) {
- s5p_dsim_interrupt_mask_set();
+ if (readl(dsim->reg_base + S5P_DSIM_INTSRC) & SwRstRelease) {
+ s5p_dsim_interrupt_mask_set(dsim);
ret = 1;
break;
}
@@ -1038,16 +1016,17 @@ void s5p_dsim_early_suspend(void)
{
u32 int_stat = 0;
pm_message_t state;
+ struct dsim_global *dsim = g_dsim;
- printk(KERN_INFO "+%s\n", __func__);
+ dev_info(dsim->dev, "+%s\n", __func__);
- if (dsim.mipi_ddi_pd->resume_complete == 0)
+ if (dsim->mipi_ddi_pd->resume_complete == 0)
return;
- dsim.mipi_ddi_pd->resume_complete = 0;
- dsim.dsim_lcd_info->lcd_enabled = 0;
+ dsim->mipi_ddi_pd->resume_complete = 0;
+ dsim->dsim_lcd_info->lcd_enabled = 0;
- /* int_stat = readl(dsim.reg_base + S5P_DSIM_INTMSK); */
+ /* int_stat = readl(dsim->reg_base + S5P_DSIM_INTMSK); */
int_stat |= ((0x01<<S5P_DSIM_INT_BTA) | (0x01<<S5P_DSIM_INT_RX_TIMEOUT) |
(0x01<<S5P_DSIM_INT_BTA_TIMEOUT) | (0x01 << S5P_DSIM_INT_RX_DONE) |
@@ -1055,134 +1034,140 @@ void s5p_dsim_early_suspend(void)
(0x01<<S5P_DSIM_INT_RX_ECC_ERR) | (0x01<<S5P_DSIM_IMT_RX_CRC_ERR) |
(0x01<<S5P_DSIM_INT_SFR_FIFO_EMPTY) | (0x01 << S5P_DSIM_INT_MSK_FRAME_DONE));
- writel(int_stat, dsim.reg_base + S5P_DSIM_INTMSK);
+ writel(int_stat, dsim->reg_base + S5P_DSIM_INTMSK);
- /* disable_irq(dsim.irq); */
+ /* disable_irq(dsim->irq); */
state.event = PM_EVENT_SUSPEND;
- if (dsim.mipi_drv->suspend)
- dsim.mipi_drv->suspend(dsim.dev, state);
+ if (dsim->mipi_drv->suspend)
+ dsim->mipi_drv->suspend(dsim->dev, state);
- if (dsim.mipi_ddi_pd->lcd_power_on)
- dsim.mipi_ddi_pd->lcd_power_on(dsim.dev, 0);
+ if (dsim->mipi_ddi_pd->lcd_power_on)
+ dsim->mipi_ddi_pd->lcd_power_on(dsim->dev, 0);
- s5p_dsim_enable_hs_clock(dsim.reg_base, 0);
- s5p_dsim_set_clock(dsim.reg_base, dsim.dsim_info->e_byte_clk, 0);
+ s5p_dsim_enable_hs_clock(dsim->reg_base, 0);
+ s5p_dsim_set_clock(dsim, dsim->dsim_info->e_byte_clk, 0);
#if defined(CONFIG_CPU_EXYNOS4210)
- writel(0x1, dsim.reg_base + S5P_DSIM_SWRST);
+ writel(0x1, dsim->reg_base + S5P_DSIM_SWRST);
#endif
- if (dsim.pd->exit_d_phy)
- dsim.pd->exit_d_phy(dsim.reg_base);
+ if (dsim->pd->exit_d_phy)
+ dsim->pd->exit_d_phy(dsim->reg_base);
- clk_disable(dsim.clock);
+ clk_disable(dsim->clock);
- if (dsim.pd->mipi_power)
- dsim.pd->mipi_power(0);
+ if (dsim->pd->mipi_power)
+ dsim->pd->mipi_power(0);
- printk(KERN_INFO "-%s\n", __func__);
+ dev_info(dsim->dev, "-%s\n", __func__);
return;
}
void s5p_dsim_late_resume(void)
{
- printk(KERN_INFO "+%s\n", __func__);
+ struct dsim_global *dsim = g_dsim;
+
+ dev_info(dsim->dev, "+%s\n", __func__);
/* MIPI SIGNAL ON */
- if (dsim.pd->mipi_power)
- dsim.pd->mipi_power(1);
+ if (dsim->pd->mipi_power)
+ dsim->pd->mipi_power(1);
- clk_enable(dsim.clock);
+ clk_enable(dsim->clock);
usleep_range(10000, 10000);
- if (dsim.mipi_ddi_pd->lcd_power_on)
- dsim.mipi_ddi_pd->lcd_power_on(dsim.dev, 1);
+ if (dsim->mipi_ddi_pd->lcd_power_on)
+ dsim->mipi_ddi_pd->lcd_power_on(dsim->dev, 1);
usleep_range(25000, 25000);
- if (dsim.mipi_ddi_pd->lcd_reset)
- dsim.mipi_ddi_pd->lcd_reset();
+ if (dsim->mipi_ddi_pd->lcd_reset)
+ dsim->mipi_ddi_pd->lcd_reset();
usleep_range(5000, 5000);
- s5p_dsim_late_resume_init_dsim(dsim.reg_base);
- s5p_dsim_init_link(dsim.reg_base);
+ s5p_dsim_late_resume_init_dsim(dsim);
+ s5p_dsim_init_link(dsim);
usleep_range(10000, 10000);
- s5p_dsim_set_hs_enable(dsim.reg_base);
- s5p_dsim_set_data_transfer_mode(dsim.reg_base, DSIM_TRANSFER_BYCPU, 1);
- s5p_dsim_set_display_mode(dsim.reg_base, dsim.dsim_lcd_info, NULL);
- s5p_dsim_set_data_transfer_mode(dsim.reg_base, DSIM_TRANSFER_BYLCDC, 1);
- /* s5p_dsim_set_interrupt_mask(dsim.reg_base, AllDsimIntr, 0); */
+ s5p_dsim_set_hs_enable(dsim);
+ s5p_dsim_set_data_transfer_mode(dsim, DSIM_TRANSFER_BYCPU, 1);
+ s5p_dsim_set_display_mode(dsim, dsim->dsim_lcd_info, NULL);
+ s5p_dsim_set_data_transfer_mode(dsim, DSIM_TRANSFER_BYLCDC, 1);
+ /* s5p_dsim_set_interrupt_mask(dsim->reg_base, AllDsimIntr, 0); */
- dsim.mipi_ddi_pd->resume_complete = 1;
+ dsim->mipi_ddi_pd->resume_complete = 1;
- printk(KERN_INFO "-%s\n", __func__);
+ dev_info(dsim->dev, "-%s\n", __func__);
return;
}
#else
#ifdef CONFIG_PM
-int s5p_dsim_suspend(struct platform_device *pdev, pm_message_t state)
+static int s5p_dsim_suspend(struct platform_device *pdev, pm_message_t state)
{
- printk(KERN_INFO "%s\n", __func__);
+ struct dsim_global *dsim = platform_get_drvdata(pdev);
+
+ dev_info(&pdev->dev, "%s\n", __func__);
- dsim.mipi_ddi_pd->resume_complete = 0;
+ dsim->mipi_ddi_pd->resume_complete = 0;
- if (dsim.mipi_drv->suspend)
- dsim.mipi_drv->suspend(&pdev->dev, state);
+ if (dsim->mipi_drv->suspend)
+ dsim->mipi_drv->suspend(&pdev->dev, state);
else
- dev_warn(&pdev->dev, "suspend func is null.\n");
+ dev_warn(&pdev->dev, "suspend func is null\n");
- clk_disable(dsim.clock);
+ clk_disable(dsim->clock);
- if (dsim.pd->mipi_power)
- dsim.pd->mipi_power(0);
+ if (dsim->pd->mipi_power)
+ dsim->pd->mipi_power(0);
else
- dev_warn(&pdev->dev, "mipi_power func is null.\n");
+ dev_warn(&pdev->dev, "mipi_power func is null\n");
return 0;
}
-int s5p_dsim_resume(struct platform_device *pdev)
+static int s5p_dsim_resume(struct platform_device *pdev)
{
u32 int_stat;
- printk(KERN_INFO "%s\n", __func__);
+ struct dsim_global *dsim = platform_get_drvdata(pdev);
+
+ dev_info(&pdev->dev, "%s\n", __func__);
- if (dsim.pd->mipi_power)
- dsim.pd->mipi_power(1);
+ if (dsim->pd->mipi_power)
+ dsim->pd->mipi_power(1);
else
- dev_warn(&pdev->dev, "mipi_power func is null.\n");
+ dev_warn(&pdev->dev, "mipi_power func is null\n");
usleep_range(10000, 10000);
- clk_enable(dsim.clock);
+ clk_enable(dsim->clock);
- if (dsim.mipi_drv->resume)
- dsim.mipi_drv->resume(&pdev->dev);
+ if (dsim->mipi_drv->resume)
+ dsim->mipi_drv->resume(&pdev->dev);
else
- dev_warn(&pdev->dev, "resume func is null.\n");
+ dev_warn(&pdev->dev, "resume func is null\n");
- s5p_dsim_init_dsim(dsim.reg_base);
- s5p_dsim_init_link(dsim.reg_base);
+ s5p_dsim_init_dsim(dsim);
+ s5p_dsim_init_link(dsim);
- s5p_dsim_set_hs_enable(dsim.reg_base);
- s5p_dsim_set_data_transfer_mode(dsim.reg_base, DSIM_TRANSFER_BYCPU, 1);
+ s5p_dsim_set_hs_enable(dsim);
+ s5p_dsim_set_data_transfer_mode(dsim, DSIM_TRANSFER_BYCPU, 1);
msleep(120);
/* initialize lcd panel */
- if (dsim.mipi_drv->init)
- dsim.mipi_drv->init(&pdev->dev);
+ if (dsim->mipi_drv->init)
+ dsim->mipi_drv->init(&pdev->dev);
else
- dev_warn(&pdev->dev, "init func is null.\n");
+ dev_warn(&pdev->dev, "init func is null\n");
- s5p_dsim_set_display_mode(dsim.reg_base, dsim.dsim_lcd_info, NULL);
+ s5p_dsim_set_display_mode(dsim, dsim->dsim_lcd_info, NULL);
- s5p_dsim_set_data_transfer_mode(dsim.reg_base, DSIM_TRANSFER_BYLCDC, 1);
+ s5p_dsim_set_data_transfer_mode(dsim, DSIM_TRANSFER_BYLCDC, 1);
- int_stat = readl(dsim.reg_base + S5P_DSIM_INTMSK);
+ int_stat = readl(dsim->reg_base + S5P_DSIM_INTMSK);
int_stat &= ~((0x01<<S5P_DSIM_INT_BTA) | (0x01<<S5P_DSIM_INT_RX_TIMEOUT) |
(0x01<<S5P_DSIM_INT_BTA_TIMEOUT) | (0x01 << S5P_DSIM_INT_RX_DONE) |
@@ -1190,9 +1175,9 @@ int s5p_dsim_resume(struct platform_device *pdev)
(0x01<<S5P_DSIM_INT_RX_ECC_ERR) | (0x01<<S5P_DSIM_IMT_RX_CRC_ERR) |
(0x01<<S5P_DSIM_INT_SFR_FIFO_EMPTY));
- writel(int_stat, dsim.reg_base + S5P_DSIM_INTMSK);
+ writel(int_stat, dsim->reg_base + S5P_DSIM_INTMSK);
- dsim.mipi_ddi_pd->resume_complete = 1;
+ dsim->mipi_ddi_pd->resume_complete = 1;
return 0;
}
@@ -1201,17 +1186,21 @@ int s5p_dsim_resume(struct platform_device *pdev)
#define s5p_dsim_resume NULL
#endif
#endif
+
u32 read_dsim_register(u32 num)
{
- return readl(dsim.reg_base + (num*4));
+ struct dsim_global *dsim = g_dsim;
+
+ return readl(dsim->reg_base + (num*4));
}
static ssize_t hs_toggle_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
char temp[3];
+ struct dsim_global *dsim = container_of(dev, struct dsim_global, panel);
- sprintf(temp, "%d\n", jiffies_to_msecs(dsim.dsim_info->hs_toggle));
+ sprintf(temp, "%d\n", jiffies_to_msecs(dsim->dsim_info->hs_toggle));
strcpy(buf, temp);
return strlen(buf);
@@ -1222,22 +1211,22 @@ static int hs_toggle_store(struct device *dev,
{
int value;
int rc;
+ struct dsim_global *dsim = container_of(dev, struct dsim_global, panel);
rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
if (rc < 0)
return rc;
else {
- dev_info(dev, "%s - %d, %d\n", __func__, jiffies_to_msecs(dsim.dsim_info->hs_toggle), value);
+ dev_info(dev, "%s - %d, %d\n", __func__, jiffies_to_msecs(dsim->dsim_info->hs_toggle), value);
if (value == 1) {
- dsim.dsim_info->hs_toggle = msecs_to_jiffies(3000);
- s5p_dsim_frame_done_interrupt_enable(1);
- schedule_delayed_work(&check_hs_toggle_work,\
- msecs_to_jiffies(120000));
+ dsim->dsim_info->hs_toggle = msecs_to_jiffies(3000);
+ s5p_dsim_frame_done_interrupt_enable(dsim, 1);
+ schedule_delayed_work(&dsim->check_hs_toggle_work, msecs_to_jiffies(120000));
} else {
- dsim.dsim_info->hs_toggle = 0;
- s5p_dsim_frame_done_interrupt_enable(0);
- cancel_delayed_work(&check_hs_toggle_work);
+ dsim->dsim_info->hs_toggle = 0;
+ s5p_dsim_frame_done_interrupt_enable(dsim, 0);
+ cancel_delayed_work(&dsim->check_hs_toggle_work);
}
}
return size;
@@ -1250,10 +1239,11 @@ static ssize_t dsim_dump_show(struct device *dev,
{
int reg_val, i;
char temp[50];
+ struct dsim_global *dsim = dev_get_drvdata(dev);
for (i = 0; i < 25; i++) {
- reg_val = readl(dsim.reg_base + i*4);
- sprintf(temp, "[DSIM]0x11c8_00%02X = 0x%08X\n", (i*4), reg_val);
+ reg_val = readl(dsim->reg_base + i*4);
+ sprintf(temp, "[DSIM]0x11C8_00%02X = 0x%08X\n", (i*4), reg_val);
strcat(buf, temp);
}
@@ -1261,43 +1251,57 @@ static ssize_t dsim_dump_show(struct device *dev,
}
static DEVICE_ATTR(dsim_dump, 0444, dsim_dump_show, NULL);
+static struct dsim_ops s5p_dsim_ops = {
+ .cmd_write = s5p_dsim_wr_data,
+ .cmd_read = s5p_dsim_rd_data,
+ .suspend = s5p_dsim_early_suspend,
+ .resume = s5p_dsim_late_resume,
+};
+
static int s5p_dsim_probe(struct platform_device *pdev)
{
struct resource *res;
int ret = -1;
u32 int_stat;
- INIT_DELAYED_WORK(&dsim_work, dsim_work_q_handler);
- INIT_DELAYED_WORK(&check_hs_toggle_work, \
- dsim_check_hs_toggle_work_q_handler);
+ struct dsim_global *dsim;
+
+ dsim = kzalloc(sizeof(struct dsim_global), GFP_KERNEL);
+ if (!dsim) {
+ pr_err("failed to allocate for dsim_global\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
- dsim.pd = to_dsim_plat(&pdev->dev);
- if (!dsim.pd) {
+ g_dsim = dsim;
+
+ dsim->pd = to_dsim_plat(&pdev->dev);
+ if (!dsim->pd) {
dev_err(&pdev->dev, "platform data is NULL\n");
return -EINVAL;
}
- dsim.dev = &pdev->dev;
+ dsim->dev = &pdev->dev;
/* set dsim config data, dsim lcd config data and lcd panel data. */
- dsim.dsim_info = dsim.pd->dsim_info;
- dsim.dsim_lcd_info = dsim.pd->dsim_lcd_info;
- dsim.lcd_panel_info = (struct s3cfb_lcd *) dsim.dsim_lcd_info->lcd_panel_info;
- dsim.mipi_ddi_pd = (struct mipi_ddi_platform_data *) dsim.dsim_lcd_info->mipi_ddi_pd;
- dsim.mipi_ddi_pd->te_irq = dsim.pd->te_irq;
+ dsim->dsim_info = dsim->pd->dsim_info;
+ dsim->dsim_lcd_info = dsim->pd->dsim_lcd_info;
+ dsim->lcd_panel_info = (struct s3cfb_lcd *) dsim->dsim_lcd_info->lcd_panel_info;
+ dsim->mipi_ddi_pd = (struct mipi_ddi_platform_data *) dsim->dsim_lcd_info->mipi_ddi_pd;
+ dsim->mipi_ddi_pd->te_irq = dsim->pd->te_irq;
- if (dsim.pd->mipi_power)
- dsim.pd->mipi_power(1);
+ if (dsim->pd->mipi_power)
+ dsim->pd->mipi_power(1);
- strcpy(dsim.pd->lcd_panel_name, dsim.lcd_panel_info->name);
+ strcpy(dsim->pd->lcd_panel_name, dsim->lcd_panel_info->name);
/* clock */
- dsim.clock = clk_get(&pdev->dev, dsim.pd->clk_name);
- if (IS_ERR(dsim.clock)) {
+ dsim->clock = clk_get(&pdev->dev, dsim->pd->clk_name);
+ if (IS_ERR(dsim->clock)) {
dev_err(&pdev->dev, "failed to get dsim clock source\n");
return -EINVAL;
}
- clk_enable(dsim.clock);
+ clk_enable(dsim->clock);
/* io memory */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1317,9 +1321,9 @@ static int s5p_dsim_probe(struct platform_device *pdev)
}
/* ioremap for register block */
- dsim.reg_base = (unsigned int) ioremap(res->start,
+ dsim->reg_base = (unsigned int)ioremap(res->start,
res->end - res->start + 1);
- if (!dsim.reg_base) {
+ if (!dsim->reg_base) {
dev_err(&pdev->dev, "failed to remap io region\n");
ret = -EINVAL;
goto err_clk_disable;
@@ -1331,15 +1335,15 @@ static int s5p_dsim_probe(struct platform_device *pdev)
ret = -EINVAL;
goto err_clk_disable;
}
- /* dsim.irq = res->start; */
+ /* dsim->irq = res->start; */
/* clear interrupt */
- /* int_stat = readl(dsim.reg_base + S5P_DSIM_INTSRC); */
+ /* int_stat = readl(dsim->reg_base + S5P_DSIM_INTSRC); */
int_stat = 0xffffffff;
- writel(int_stat, dsim.reg_base + S5P_DSIM_INTSRC);
+ writel(int_stat, dsim->reg_base + S5P_DSIM_INTSRC);
/* enable interrupts */
- int_stat = readl(dsim.reg_base + S5P_DSIM_INTMSK);
+ int_stat = readl(dsim->reg_base + S5P_DSIM_INTMSK);
int_stat &= ~((0x01<<S5P_DSIM_INT_BTA) | (0x01<<S5P_DSIM_INT_RX_TIMEOUT) |
(0x01<<S5P_DSIM_INT_BTA_TIMEOUT) | (0x01 << S5P_DSIM_INT_RX_DONE) |
@@ -1347,68 +1351,77 @@ static int s5p_dsim_probe(struct platform_device *pdev)
(0x01<<S5P_DSIM_INT_RX_ECC_ERR) | (0x01<<S5P_DSIM_IMT_RX_CRC_ERR) |
(0x01<<S5P_DSIM_INT_SFR_FIFO_EMPTY));
- writel(int_stat, dsim.reg_base + S5P_DSIM_INTMSK);
+ writel(int_stat, dsim->reg_base + S5P_DSIM_INTMSK);
init_completion(&dsim_rd_comp);
init_completion(&dsim_wr_comp);
mutex_init(&dsim_rd_wr_mutex);
- dsim.mipi_ddi_pd->resume_complete = 1;
- dsim.dsim_lcd_info->lcd_enabled = 1;
+ dsim->mipi_ddi_pd->resume_complete = 1;
+ dsim->dsim_lcd_info->lcd_enabled = 1;
- ret = request_irq(res->start, (void *)s5p_dsim_isr, IRQF_DISABLED, pdev->name, &dsim);
+ ret = request_irq(res->start, (void *)s5p_dsim_isr, IRQF_DISABLED, pdev->name, dsim);
if (ret != 0) {
dev_err(&pdev->dev, "failed to request dsim irq\n");
ret = -EINVAL;
goto err_clk_disable;
}
- /* find lcd panel driver registered to mipi-dsi driver. */
- dsim.mipi_drv = scan_mipi_driver(dsim.pd->lcd_panel_name);
- if (dsim.mipi_drv == NULL) {
- dev_err(&pdev->dev, "mipi_drv is NULL.\n");
+ INIT_DELAYED_WORK(&dsim->dsim_work, dsim_work_q_handler);
+ INIT_DELAYED_WORK(&dsim->check_hs_toggle_work, dsim_check_hs_toggle_work_q_handler);
+
+ dsim->ops = &s5p_dsim_ops;
+
+ platform_set_drvdata(pdev, dsim);
+
+ dsim->panel.parent = &pdev->dev;
+ dev_set_name(&dsim->panel, dsim->pd->lcd_panel_name);
+ ret = device_register(&dsim->panel);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "faild device register\n");
ret = -EINVAL;
goto mipi_drv_err;
}
- /* set lcd panel driver link */
- ret = dsim.mipi_drv->set_link((void *) dsim.mipi_ddi_pd, dsim.reg_base,
- s5p_dsim_wr_data, s5p_dsim_rd_data);
- if (ret < 0) {
- dev_err(&pdev->dev, "[DSIM : ERROR] faild set_link()\n");
+ /* find lcd panel driver registered to mipi-dsi driver. */
+ dsim->mipi_drv = scan_mipi_driver(dsim, dsim->pd->lcd_panel_name);
+ if (dsim->mipi_drv == NULL) {
+ dev_err(&pdev->dev, "mipi_drv is NULL\n");
ret = -EINVAL;
goto mipi_drv_err;
}
- ret = dsim.mipi_drv->probe(&pdev->dev);
+ ret = dsim->mipi_drv->probe(&dsim->panel);
if (ret < 0) {
- dev_err(&pdev->dev, "[DSIM : ERROR] faild probe()\n");
+ dev_err(&pdev->dev, "faild probe\n");
ret = -EINVAL;
goto mipi_drv_err;
}
- dsim.state = DSIM_STATE_HSCLKEN;
+ dsim->state = DSIM_STATE_HSCLKEN;
ret = device_create_file(&(pdev->dev), &dev_attr_dsim_dump);
if (ret < 0)
dev_err(&pdev->dev, "failed to add sysfs entries, %d\n", __LINE__);
- ret = device_create_file(&(pdev->dev), &dev_attr_hs_toggle);
- if (ret < 0)
- dev_err(&pdev->dev, "failed to add sysfs entries, %d\n", __LINE__);
+ if (!dsim->dsim_info->hs_toggle) {
+ ret = device_create_file(&dsim->panel, &dev_attr_hs_toggle);
+ if (ret < 0)
+ dev_err(&pdev->dev, "failed to add sysfs entries, %d\n", __LINE__);
+ }
- if (dsim.dsim_info->hs_toggle)
- s5p_dsim_frame_done_interrupt_enable(1);
+ if (dsim->dsim_info->hs_toggle)
+ s5p_dsim_frame_done_interrupt_enable(dsim, 1);
- dev_info(&pdev->dev, "mipi-dsi driver has been probed.\n");
+ dev_info(&pdev->dev, "mipi-dsi driver has been probed\n");
#if 0
#ifdef CONFIG_HAS_WAKELOCK
#ifdef CONFIG_HAS_EARLYSUSPEND
- dsim.early_suspend.suspend = s5p_dsim_early_suspend;
- dsim.early_suspend.resume = s5p_dsim_late_resume;
- dsim.early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1;
- register_early_suspend(&dsim.early_suspend);
+ dsim->early_suspend.suspend = s5p_dsim_early_suspend;
+ dsim->early_suspend.resume = s5p_dsim_late_resume;
+ dsim->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1;
+ register_early_suspend(&dsim->early_suspend);
#endif
#endif
#endif
@@ -1416,11 +1429,11 @@ static int s5p_dsim_probe(struct platform_device *pdev)
mipi_drv_err:
free_irq(res->start, &dsim);
- dsim.pd->mipi_power(0);
+ dsim->pd->mipi_power(0);
err_clk_disable:
- clk_disable(dsim.clock);
-
+ clk_disable(dsim->clock);
+err_alloc:
return ret;
}
diff --git a/drivers/video/samsung/s5p-dsim.h b/drivers/video/samsung/s5p-dsim.h
index 77870a0..baf8f66 100644
--- a/drivers/video/samsung/s5p-dsim.h
+++ b/drivers/video/samsung/s5p-dsim.h
@@ -34,9 +34,6 @@ struct mipi_lcd_driver {
s32 (*init)(struct device *dev);
void (*display_on)(struct device *dev);
- s32 (*set_link)(void *pd, u32 dsim_base,
- u8 (*cmd_write)(u32 dsim_base, u32 data0, u32 data1, u32 data2),
- int (*cmd_read)(u32 reg_base, u8 addr, u16 count, u8 *buf));
s32 (*probe)(struct device *dev);
s32 (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
@@ -44,6 +41,47 @@ struct mipi_lcd_driver {
s32 (*resume)(struct device *dev);
};
+struct dsim_ops {
+ u8 (*cmd_write)(void *ptr, u32 data0, u32 data1, u32 data2);
+ int (*cmd_read)(void *ptr, u8 addr, u16 count, u8 *buf);
+ void (*suspend)(void);
+ void (*resume)(void);
+};
+
+/* Indicates the state of the device */
+struct dsim_global {
+ struct device *dev;
+ struct device panel;
+ struct clk *clock;
+ struct s5p_platform_dsim *pd;
+ struct dsim_config *dsim_info;
+ struct dsim_lcd_config *dsim_lcd_info;
+ /* lcd panel data. */
+ struct s3cfb_lcd *lcd_panel_info;
+ /* platform and machine specific data for lcd panel driver. */
+ struct mipi_ddi_platform_data *mipi_ddi_pd;
+ /* lcd panel driver based on MIPI-DSI. */
+ struct mipi_lcd_driver *mipi_drv;
+
+ unsigned int irq;
+ unsigned int te_irq;
+ unsigned int reg_base;
+ unsigned char state;
+ unsigned int data_lane;
+ enum dsim_byte_clk_src e_clk_src;
+ unsigned long hs_clk;
+ unsigned long byte_clk;
+ unsigned long escape_clk;
+ unsigned char freq_band;
+ char header_fifo_index[DSIM_HEADER_FIFO_SZ];
+
+ struct delayed_work dsim_work;
+ struct delayed_work check_hs_toggle_work;
+ unsigned int dsim_toggle_per_frame_count;
+
+ struct dsim_ops *ops;
+};
+
int s5p_dsim_register_lcd_driver(struct mipi_lcd_driver *lcd_drv);
#endif /* _S5P_DSIM_LOWLEVEL_H */
diff --git a/drivers/video/samsung/s6d6aa1.c b/drivers/video/samsung/s6d6aa1.c
index 2efb506..2a4c4ad 100644
--- a/drivers/video/samsung/s6d6aa1.c
+++ b/drivers/video/samsung/s6d6aa1.c
@@ -37,7 +37,7 @@
#define MIN_BRIGHTNESS 0
#define MAX_BRIGHTNESS 255
-#define DEFAULT_BRIGHTNESS 160
+#define DEFAULT_BRIGHTNESS 170
struct lcd_info {
unsigned int bl;
@@ -57,9 +57,9 @@ struct lcd_info {
unsigned int irq;
unsigned int connected;
-};
-static struct mipi_ddi_platform_data *ddi_pd;
+ struct dsim_global *dsim;
+};
static const unsigned char SEQ_SLPOUT[] = {
0x11,
@@ -67,13 +67,13 @@ static const unsigned char SEQ_SLPOUT[] = {
0x00
};
-static unsigned char SEQ_DSCTL[] = {
+static const unsigned char SEQ_DSCTL[] = {
0x36,
0x00,
0x00
};
-static unsigned char SEQ_WRDISBV[] = {
+static const unsigned char SEQ_WRDISBV[] = {
0x51,
0xFF,
0x00
@@ -109,6 +109,13 @@ static const unsigned char SEQ_SLPIN[] = {
0x00
};
+static unsigned char SEQ_WRDISBV_CTL[] = {
+ 0x51,
+ 0xFF,
+ 0x00
+};
+
+
static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
int size;
@@ -123,11 +130,11 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
wbuf = seq;
if (size == 1)
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_WR_NO_PARA, wbuf[0], 0);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
else if (size == 2)
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
else
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_LONG_WR, (unsigned int)wbuf, size);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
mutex_unlock(&lcd->lock);
@@ -143,44 +150,14 @@ static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf
mutex_lock(&lcd->lock);
- if (ddi_pd->cmd_read)
- ret = ddi_pd->cmd_read(ddi_pd->dsim_base, addr, count, buf);
+ if (lcd->dsim->ops->cmd_read)
+ ret = lcd->dsim->ops->cmd_read(lcd->dsim, addr, count, buf);
mutex_unlock(&lcd->lock);
return ret;
}
-static int s6e8ax0_set_link(void *pd, unsigned int dsim_base,
- unsigned char (*cmd_write) (unsigned int dsim_base, unsigned int data0,
- unsigned int data1, unsigned int data2),
- int (*cmd_read) (u32 reg_base, u8 addr, u16 count, u8 *buf))
-{
- struct mipi_ddi_platform_data *temp_pd = NULL;
-
- temp_pd = (struct mipi_ddi_platform_data *) pd;
- if (temp_pd == NULL) {
- printk(KERN_ERR "mipi_ddi_platform_data is null.\n");
- return -EPERM;
- }
-
- ddi_pd = temp_pd;
-
- ddi_pd->dsim_base = dsim_base;
-
- if (cmd_write)
- ddi_pd->cmd_write = cmd_write;
- else
- printk(KERN_WARNING "cmd_write function is null.\n");
-
- if (cmd_read)
- ddi_pd->cmd_read = cmd_read;
- else
- printk(KERN_WARNING "cmd_read function is null.\n");
-
- return 0;
-}
-
static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
{
int ret = 0;
@@ -231,8 +208,9 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
if ((force) || ((lcd->ldi_enable) && (lcd->current_bl != lcd->bl))) {
lcd->current_bl = lcd->bl;
- SEQ_WRDISBV[1] = lcd->bl;
- s6e8ax0_write(lcd, SEQ_WRDISBV, ARRAY_SIZE(SEQ_WRDISBV));
+ SEQ_WRDISBV_CTL[1] = lcd->bl;
+ s6e8ax0_write(lcd, SEQ_WRDISBV_CTL, \
+ ARRAY_SIZE(SEQ_WRDISBV_CTL));
dev_info(&lcd->ld->dev, "brightness=%d, bl=%d\n", brightness, lcd->bl);
}
@@ -250,7 +228,7 @@ static int s6e8ax0_ldi_init(struct lcd_info *lcd)
msleep(200);
- s6e8ax0_write(lcd, SEQ_DSCTL, ARRAY_SIZE(SEQ_WRDISBV));
+ s6e8ax0_write(lcd, SEQ_DSCTL, ARRAY_SIZE(SEQ_DSCTL));
s6e8ax0_write(lcd, SEQ_WRDISBV, ARRAY_SIZE(SEQ_WRDISBV));
s6e8ax0_write(lcd, SEQ_WRCTRLD, ARRAY_SIZE(SEQ_WRCTRLD));
s6e8ax0_write(lcd, SEQ_WRCABC, ARRAY_SIZE(SEQ_WRCABC));
@@ -459,6 +437,8 @@ void s6e8ax0_early_suspend(void)
{
struct lcd_info *lcd = g_lcd;
+ set_dsim_lcd_enabled(0);
+
dev_info(&lcd->ld->dev, "+%s\n", __func__);
s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
@@ -478,7 +458,7 @@ void s6e8ax0_late_resume(void)
dev_info(&lcd->ld->dev, "-%s\n", __func__);
- set_dsim_lcd_enabled();
+ set_dsim_lcd_enabled(1);
return ;
}
@@ -526,6 +506,7 @@ static int s6e8ax0_probe(struct device *dev)
}
lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
lcd->bl = 0;
@@ -591,7 +572,6 @@ static void s6e8ax0_shutdown(struct device *dev)
static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
.name = "s6d6aa1",
- .set_link = s6e8ax0_set_link,
.probe = s6e8ax0_probe,
.remove = __devexit_p(s6e8ax0_remove),
.shutdown = s6e8ax0_shutdown,
diff --git a/drivers/video/samsung/s6dr171.c b/drivers/video/samsung/s6dr171.c
index b48e40a..167f658 100644
--- a/drivers/video/samsung/s6dr171.c
+++ b/drivers/video/samsung/s6dr171.c
@@ -76,10 +76,9 @@ struct lcd_info {
unsigned int irq;
unsigned int connected;
+ struct dsim_global *dsim;
};
-static struct mipi_ddi_platform_data *ddi_pd;
-
static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
int size;
@@ -94,11 +93,11 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
wbuf = seq;
if (size == 1)
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_WR_NO_PARA, wbuf[0], 0);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
else if (size == 2)
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
else
- ddi_pd->cmd_write(ddi_pd->dsim_base, DCS_LONG_WR, (unsigned int)wbuf, size);
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
mutex_unlock(&lcd->lock);
@@ -114,44 +113,14 @@ static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf
mutex_lock(&lcd->lock);
- if (ddi_pd->cmd_read)
- ret = ddi_pd->cmd_read(ddi_pd->dsim_base, addr, count, buf);
+ if (lcd->dsim->ops->cmd_read)
+ ret = lcd->dsim->ops->cmd_read(lcd->dsim, addr, count, buf);
mutex_unlock(&lcd->lock);
return ret;
}
-static int s6e8ax0_set_link(void *pd, unsigned int dsim_base,
- unsigned char (*cmd_write) (unsigned int dsim_base, unsigned int data0,
- unsigned int data1, unsigned int data2),
- int (*cmd_read) (u32 reg_base, u8 addr, u16 count, u8 *buf))
-{
- struct mipi_ddi_platform_data *temp_pd = NULL;
-
- temp_pd = (struct mipi_ddi_platform_data *) pd;
- if (temp_pd == NULL) {
- printk(KERN_ERR "mipi_ddi_platform_data is null.\n");
- return -EPERM;
- }
-
- ddi_pd = temp_pd;
-
- ddi_pd->dsim_base = dsim_base;
-
- if (cmd_write)
- ddi_pd->cmd_write = cmd_write;
- else
- printk(KERN_WARNING "cmd_write function is null.\n");
-
- if (cmd_read)
- ddi_pd->cmd_read = cmd_read;
- else
- printk(KERN_WARNING "cmd_read function is null.\n");
-
- return 0;
-}
-
static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
{
int ret = 0;
@@ -424,6 +393,8 @@ void s6e8ax0_early_suspend(void)
{
struct lcd_info *lcd = g_lcd;
+ set_dsim_lcd_enabled(0);
+
dev_info(&lcd->ld->dev, "+%s\n", __func__);
s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
@@ -439,7 +410,7 @@ void s6e8ax0_late_resume(void)
s6e8ax0_power(lcd, FB_BLANK_UNBLANK);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
- set_dsim_lcd_enabled();
+ set_dsim_lcd_enabled(1);
return ;
}
@@ -496,6 +467,7 @@ static int s6e8ax0_probe(struct device *dev)
}
lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
lcd->bl = DEFAULT_GAMMA_LEVEL;
@@ -577,7 +549,6 @@ static void s6e8ax0_shutdown(struct device *dev)
static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
.name = "s6e8aa0",
- .set_link = s6e8ax0_set_link,
.probe = s6e8ax0_probe,
.remove = __devexit_p(s6e8ax0_remove),
.shutdown = s6e8ax0_shutdown,
diff --git a/drivers/video/samsung/s6e8aa0_param.h b/drivers/video/samsung/s6e8aa0_param.h
index b40932d..3ac11ad 100644
--- a/drivers/video/samsung/s6e8aa0_param.h
+++ b/drivers/video/samsung/s6e8aa0_param.h
@@ -55,13 +55,13 @@ enum {
#define ELVSS_OFFSET_300 0x00
#define ELVSS_OFFSET_200 0x08
#define ELVSS_OFFSET_160 0x0D
-#if defined(CONFIG_MACH_Q1_BD)
+#if defined(CONFIG_S6E8AA0_AMS529HA01)
#define ELVSS_OFFSET_100 0x11
#else
#define ELVSS_OFFSET_100 0x12
#endif
-#if defined(CONFIG_MACH_Q1_BD)
+#if defined(CONFIG_S6E8AA0_AMS529HA01)
#define ELVSS_OFFSET_MAX ELVSS_OFFSET_300
#define ELVSS_OFFSET_1 ELVSS_OFFSET_200
#define ELVSS_OFFSET_2 ELVSS_OFFSET_160
diff --git a/drivers/video/samsung/smart_dimming.c b/drivers/video/samsung/smart_dimming.c
index a1c428d..d356009 100644
--- a/drivers/video/samsung/smart_dimming.c
+++ b/drivers/video/samsung/smart_dimming.c
@@ -20,7 +20,7 @@
#define V1_255_calc_param (V1_255_div_1000 / VREG_OUT_1000)
#endif
-#ifdef CONFIG_MACH_Q1_BD
+#if defined(CONFIG_S6E8AA0_AMS529HA01)
#define VREG_OUT_1000 4600
#else
#ifdef CONFIG_AID_DIMMING