aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Hillenbrand <codeworkx@cyanogenmod.org>2013-06-04 01:33:22 +0200
committerDaniel Hillenbrand <codeworkx@cyanogenmod.org>2013-06-04 12:54:26 +0200
commit55bb2048feb59f2190f704c2a4df81b557b55c7a (patch)
treecbb680a60770fb762e5b27c502ad71c2366bf604
parent3d8b293a4f5042cd9fdc4009a40f6483371cd489 (diff)
downloadkernel_samsung_smdk4412-55bb2048feb59f2190f704c2a4df81b557b55c7a.tar.gz
kernel_samsung_smdk4412-55bb2048feb59f2190f704c2a4df81b557b55c7a.tar.bz2
kernel_samsung_smdk4412-55bb2048feb59f2190f704c2a4df81b557b55c7a.zip
smdk4412: bulk update from i9300 update 9
Change-Id: Icd3e7b601f3f4c8b3dcf053fed5819fb7caf5296
-rw-r--r--arch/arm/mach-exynos/mach-midas.c22
-rw-r--r--arch/arm/mach-exynos/midas-sound.c7
-rw-r--r--drivers/battery/max77693_charger.c31
-rw-r--r--drivers/battery/samsung_battery.c14
-rw-r--r--drivers/gpu/ion/ion.c4
-rw-r--r--drivers/misc/max77693-muic.c555
-rw-r--r--drivers/mmc/card/Kconfig7
-rw-r--r--drivers/mmc/card/Makefile4
-rw-r--r--drivers/mmc/card/block.c118
-rw-r--r--drivers/mmc/card/cprmdrv_samsung.c35
-rw-r--r--drivers/mmc/card/cprmdrv_samsung.h14
-rw-r--r--drivers/mmc/core/mmc.c74
-rw-r--r--drivers/mmc/core/mmc_ops.c60
-rw-r--r--drivers/usb/core/sec-dock.h4
-rw-r--r--include/linux/battery/samsung_battery.h11
-rw-r--r--include/linux/mfd/max77693-private.h2
-rw-r--r--include/linux/mfd/max77693.h4
-rw-r--r--include/linux/mmc/card.h5
-rw-r--r--include/linux/mmc/ioctl.h2
-rw-r--r--include/linux/mmc/mmc.h2
-rw-r--r--mm/cma.c8
-rw-r--r--mm/page_alloc-cma.c2
-rw-r--r--sound/soc/codecs/wm8994.c2
23 files changed, 780 insertions, 207 deletions
diff --git a/arch/arm/mach-exynos/mach-midas.c b/arch/arm/mach-exynos/mach-midas.c
index f462c8a668d..c2de56be4b4 100644
--- a/arch/arm/mach-exynos/mach-midas.c
+++ b/arch/arm/mach-exynos/mach-midas.c
@@ -835,9 +835,10 @@ static struct s3c_mshci_platdata exynos4_mshc_pdata __initdata = {
MMC_CAP_UHS_DDR50 | MMC_CAP_CMD23,
#ifdef CONFIG_MMC_MSHCI_ENABLE_CACHE
.host_caps2 = MMC_CAP2_ADAPT_PACKED | MMC_CAP2_PACKED_CMD |
- MMC_CAP2_CACHE_CTRL,
+ MMC_CAP2_CACHE_CTRL | MMC_CAP2_POWEROFF_NOTIFY,
#else
- .host_caps2 = MMC_CAP2_ADAPT_PACKED | MMC_CAP2_PACKED_CMD,
+ .host_caps2 = MMC_CAP2_ADAPT_PACKED | MMC_CAP2_PACKED_CMD |
+ MMC_CAP2_POWEROFF_NOTIFY,
#endif
#elif defined(CONFIG_EXYNOS4_MSHC_8BIT)
.max_width = 8,
@@ -3430,29 +3431,16 @@ static void __init exynos4_reserve(void)
.start = 0x65800000,
.reserved = 1,
};
-
+
if (cma_early_region_register(&fimc_reg))
pr_err("S5P/CMA: Failed to register '%s'\n",
- fimc_reg.name);
+ fimc_reg.name);
}
#endif
#if defined(CONFIG_USE_MFC_CMA) && defined(CONFIG_MACH_M0)
ret = dma_declare_contiguous(&s5p_device_mfc.dev,
0x02800000, 0x5C800000, 0);
-
- if (ret == 0) {
- static struct cma_region mfc_reg = {
- .name = "mfc",
- .size = 0x02800000,
- .start = 0x5C800000,
- .reserved = 1,
- };
-
- if (cma_early_region_register(&mfc_reg))
- pr_err("S5P/CMA: Failed to register '%s'\n",
- mfc_reg.name);
- }
#endif
if (ret != 0)
printk(KERN_ERR "%s Fail\n", __func__);
diff --git a/arch/arm/mach-exynos/midas-sound.c b/arch/arm/mach-exynos/midas-sound.c
index 28c7cbdf3eb..32ab8661472 100644
--- a/arch/arm/mach-exynos/midas-sound.c
+++ b/arch/arm/mach-exynos/midas-sound.c
@@ -331,11 +331,16 @@ struct platform_device s3c_device_fm34 = {
defined(CONFIG_FM_SI4705_MODULE)
static void fmradio_power(int on)
{
+ int err;
#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M0_CTC)
gpio_set_value(si47xx_data.gpio_sw, GPIO_LEVEL_HIGH);
#endif
if (on) {
- gpio_request(GPIO_FM_INT, "GPC1");
+ err = gpio_request(GPIO_FM_INT, "GPC1");
+ if (err) {
+ pr_err(KERN_ERR "GPIO_FM_INT GPIO set error!\n");
+ return;
+ }
gpio_direction_output(GPIO_FM_INT, 1);
gpio_set_value(si47xx_data.gpio_rst, GPIO_LEVEL_LOW);
gpio_set_value(GPIO_FM_INT, GPIO_LEVEL_LOW);
diff --git a/drivers/battery/max77693_charger.c b/drivers/battery/max77693_charger.c
index 4a147ee9f83..35289a671e7 100644
--- a/drivers/battery/max77693_charger.c
+++ b/drivers/battery/max77693_charger.c
@@ -463,7 +463,8 @@ void max77693_set_input_current(struct max77693_charger_data *chg_data,
#endif
if (set_current == OFF_CURR) {
- max77693_write_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_09, set_current);
+ max77693_write_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_09,
+ set_current);
if (chg_data->soft_reg_state == true) {
pr_info("%s: exit soft regulation loop\n", __func__);
@@ -676,11 +677,12 @@ 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 dtls_01, chg_dtls;
u8 mu_st2, chgdetrun, vbvolt, chgtyp, dxovp;
- int muic_cb_typ;
+#ifdef CONFIG_BATTERY_WPC_CHARGER
bool wc_state;
- bool retry_det;
- bool chg_det_erred = false; /* TEMP: set as true for logging */
+#endif
+ bool retry_det, chg_det_erred;
bool otg_detected = false;
int retry_cnt = 0;
pr_debug("%s\n", __func__);
@@ -719,10 +721,8 @@ static int max77693_get_cable_type(struct max77693_charger_data *chg_data)
}
#endif
- muic_cb_typ = max77693_muic_get_charging_type();
/* if type detection by otg, do not otg check */
- if ((muic_cb_typ != CABLE_TYPE_AUDIODOCK_MUIC) &&
- (((otg || (mu_adc == 0x00 && !mu_adc1k))))) {
+ if (otg || (mu_adc == 0x00 && !mu_adc1k)) {
pr_info("%s: otg enabled(otg(0x%x), adc(0x%x))\n",
__func__, otg, mu_adc);
state = POWER_SUPPLY_TYPE_BATTERY;
@@ -737,15 +737,20 @@ static int max77693_get_cable_type(struct max77693_charger_data *chg_data)
goto chg_det_finish;
}
+ chg_det_erred = false; /* TEMP: set as true for logging */
do {
retry_det = false;
max77693_read_reg(chg_data->max77693->i2c,
MAX77693_CHG_REG_CHG_DTLS_00, &dtls_00);
+ max77693_read_reg(chg_data->max77693->i2c,
+ MAX77693_CHG_REG_CHG_DTLS_01, &dtls_01);
max77693_read_reg(chg_data->max77693->muic,
MAX77693_MUIC_REG_STATUS2, &mu_st2);
chgin_dtls = ((dtls_00 & MAX77693_CHGIN_DTLS) >>
MAX77693_CHGIN_DTLS_SHIFT);
+ chg_dtls = ((dtls_01 & MAX77693_CHG_DTLS) >>
+ MAX77693_CHG_DTLS_SHIFT);
chgdetrun = ((mu_st2 & MAX77693_CHGDETRUN) >>
MAX77693_CHGDETRUN_SHIFT);
vbvolt = ((mu_st2 & MAX77693_VBVOLT) >>
@@ -753,9 +758,9 @@ 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_err("%s: CHGIN(0x%x). MU_ST2(0x%x), "
+ pr_err("%s: CHGIN(0x%x). CHG(0x%x), MU_ST2(0x%x), "
"CDR(0x%x), VB(0x%x), CHGTYP(0x%x)\n", __func__,
- chgin_dtls, mu_st2,
+ chgin_dtls, chg_dtls, mu_st2,
chgdetrun, vbvolt, chgtyp);
/* input power state */
@@ -772,9 +777,7 @@ static int max77693_get_cable_type(struct max77693_charger_data *chg_data)
chg_det_erred = true;
/* check chargable input power */
- if ((chgin_dtls == 0x0) &&
- (chg_data->cable_type ==
- POWER_SUPPLY_TYPE_BATTERY)) {
+ if ((chgin_dtls == 0x0) && (chg_dtls == 0x8)) {
pr_err("%s: unchargable power\n", __func__);
state = POWER_SUPPLY_TYPE_BATTERY;
goto chg_det_finish;
@@ -974,10 +977,6 @@ static int max77693_get_online_type(struct max77693_charger_data *chg_data)
m_typ = max77693_get_cable_type(chg_data);
- pr_info("%s: main(%d), sub(%d), pwr(%d)\n", __func__, m_typ,
- chg_data->cable_sub_type,
- chg_data->cable_pwr_type);
-
state = ((m_typ << ONLINE_TYPE_MAIN_SHIFT) |
(chg_data->cable_sub_type << ONLINE_TYPE_SUB_SHIFT) |
(chg_data->cable_pwr_type << ONLINE_TYPE_PWR_SHIFT));
diff --git a/drivers/battery/samsung_battery.c b/drivers/battery/samsung_battery.c
index c63430bd1df..ffe10e9263e 100644
--- a/drivers/battery/samsung_battery.c
+++ b/drivers/battery/samsung_battery.c
@@ -637,7 +637,7 @@ static void battery_notify_full_state(struct battery_info *info)
info->battery_raw_soc, info->battery_full_soc,
info->battery_soc);
- if ((info->recharge_phase && info->full_charged_state) ||
+ if (info->full_charged_state ||
((info->charge_real_state != POWER_SUPPLY_STATUS_DISCHARGING) &&
(info->battery_raw_soc > info->battery_full_soc) &&
(info->battery_soc == 100))) {
@@ -808,7 +808,7 @@ static bool battery_fullcharged_cond(struct battery_info *info)
if (info->charge_real_state == POWER_SUPPLY_STATUS_FULL) {
if ((info->battery_vcell > f_cond_vcell) &&
(info->battery_soc > f_cond_soc)) {
- pr_info("%s: real full charged, v(%d), s(%d)\n",
+ pr_debug("%s: real full charged, v(%d), s(%d)\n",
__func__, info->battery_vcell,
info->battery_soc);
#if defined(USE_2STEP_TERM)
@@ -1606,6 +1606,8 @@ charge_ok:
case POWER_SUPPLY_TYPE_DOCK:
if (!info->pdata->suspend_chging)
wake_lock(&info->charge_wake_lock);
+ /* default dock prop is AC */
+ info->online_prop = ONLINE_PROP_AC;
muic_cb_typ = max77693_muic_get_charging_type();
switch (muic_cb_typ) {
case CABLE_TYPE_AUDIODOCK_MUIC:
@@ -1633,6 +1635,7 @@ charge_ok:
case CABLE_TYPE_SMARTDOCK_USB_MUIC:
pr_info("%s: smart dock usb(low), %d\n",
__func__, DOCK_TYPE_LOW_CURR);
+ info->online_prop = ONLINE_PROP_USB;
battery_charge_control(info,
DOCK_TYPE_LOW_CURR,
DOCK_TYPE_LOW_CURR);
@@ -2037,7 +2040,9 @@ static int samsung_usb_get_property(struct power_supply *ps,
val->intval = ((info->charge_virt_state !=
POWER_SUPPLY_STATUS_DISCHARGING) &&
((info->cable_type == POWER_SUPPLY_TYPE_USB) ||
- (info->cable_type == POWER_SUPPLY_TYPE_USB_CDP)));
+ (info->cable_type == POWER_SUPPLY_TYPE_USB_CDP) ||
+ ((info->cable_type == POWER_SUPPLY_TYPE_DOCK) &&
+ (info->online_prop == ONLINE_PROP_USB))));
return 0;
}
@@ -2057,7 +2062,8 @@ static int samsung_ac_get_property(struct power_supply *ps,
POWER_SUPPLY_STATUS_DISCHARGING) &&
((info->cable_type == POWER_SUPPLY_TYPE_MAINS) ||
(info->cable_type == POWER_SUPPLY_TYPE_MISC) ||
- (info->cable_type == POWER_SUPPLY_TYPE_DOCK) ||
+ ((info->cable_type == POWER_SUPPLY_TYPE_DOCK) &&
+ (info->online_prop != ONLINE_PROP_USB)) ||
(info->cable_type == POWER_SUPPLY_TYPE_WIRELESS)));
return 0;
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index eb81503642e..14dbefcab97 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1034,8 +1034,8 @@ static int ion_share_mmap(struct file *file, struct vm_area_struct *vma)
return -EINVAL;
}
- if ((size > buffer->size) || (size + (vma->vm_pgoff << PAGE_SHIFT) >
- buffer->size)) {
+ if (((vma->vm_pgoff << PAGE_SHIFT) >= buffer->size) ||
+ (size > (buffer->size - (vma->vm_pgoff << PAGE_SHIFT)))) {
pr_err("%s: trying to map larger area than handle has available"
"\n", __func__);
ret = -EINVAL;
diff --git a/drivers/misc/max77693-muic.c b/drivers/misc/max77693-muic.c
index 41008a0b881..9a78d762247 100644
--- a/drivers/misc/max77693-muic.c
+++ b/drivers/misc/max77693-muic.c
@@ -92,6 +92,7 @@ enum {
ADC_DOCK_VOL_UP = 0x0b, /* 0x01011 17.26K ohm */
ADC_DOCK_PLAY_PAUSE_KEY = 0x0d,
ADC_SMARTDOCK = 0x10, /* 0x10000 40.2K ohm */
+ ADC_AUDIODOCK = 0x12, /* 0x10010 64.9K ohm */
ADC_CEA936ATYPE1_CHG = 0x17, /* 0x10111 200K ohm */
ADC_JIG_USB_OFF = 0x18, /* 0x11000 255K ohm */
ADC_JIG_USB_ON = 0x19, /* 0x11001 301K ohm */
@@ -135,6 +136,11 @@ struct max77693_muic_info {
struct wake_lock muic_wake_lock;
enum cable_type_muic cable_type;
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK) ||\
+ defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
+ struct delayed_work dock_work;
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK ||
+ CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
struct delayed_work init_work;
struct delayed_work usb_work;
struct delayed_work mhl_work;
@@ -151,6 +157,10 @@ struct max77693_muic_info {
bool is_otg_attach_blocked;
#endif /* CONFIG_MACH_GC1 */
+#if !defined(CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK)
+ bool is_factory_start;
+#endif /* !CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK */
+
#if defined(CONFIG_MUIC_DET_JACK)
int earkeypressed;
int previous_earkey;
@@ -175,8 +185,8 @@ static int get_if_pmic_inifo(char *str)
get_option(&str, &if_muic_info);
switch_sel = if_muic_info & 0x0f;
if_pmic_rev = (if_muic_info & 0xf0) >> 4;
- pr_info("%s: switch_sel: %x if_pmic_rev:%x\n",
- __func__, switch_sel, if_pmic_rev);
+ pr_info("%s %s: switch_sel: %x if_pmic_rev:%x\n",
+ __FILE__, __func__, switch_sel, if_pmic_rev);
return if_muic_info;
}
__setup("pmic_info=", get_if_pmic_inifo);
@@ -441,6 +451,14 @@ static ssize_t max77693_muic_show_device(struct device *dev,
return sprintf(buf, "mHL\n");
case CABLE_TYPE_MHL_VB_MUIC:
return sprintf(buf, "mHL charging\n");
+ case CABLE_TYPE_SMARTDOCK_MUIC:
+ return sprintf(buf, "Smart Dock\n");
+ case CABLE_TYPE_SMARTDOCK_TA_MUIC:
+ return sprintf(buf, "Smart Dock+TA\n");
+ case CABLE_TYPE_SMARTDOCK_USB_MUIC:
+ return sprintf(buf, "Smart Dock+USB\n");
+ case CABLE_TYPE_AUDIODOCK_MUIC:
+ return sprintf(buf, "Audio Dock\n");
default:
break;
}
@@ -934,6 +952,49 @@ static ssize_t max77693_muic_set_otg_block(struct device *dev,
}
#endif /* CONFIG_MACH_GC1 */
+#if !defined(CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK)
+static ssize_t max77693_muic_show_apo_factory(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct max77693_muic_info *info = dev_get_drvdata(dev);
+ const char *mode;
+
+ /* true: Factory mode, false: not Factory mode */
+ if (info->is_factory_start)
+ mode = "FACTORY_MODE";
+ else
+ mode = "NOT_FACTORY_MODE";
+
+ pr_info("%s:%s apo factory=%s\n", DEV_NAME, __func__, mode);
+
+ return sprintf(buf, "%s\n", mode);
+}
+
+static ssize_t max77693_muic_set_apo_factory(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct max77693_muic_info *info = dev_get_drvdata(dev);
+ const char *mode;
+
+ pr_info("%s:%s buf:%s\n", DEV_NAME, __func__, buf);
+
+ /* "FACTORY_START": factory mode */
+ if (!strncmp(buf, "FACTORY_START", 13)) {
+ info->is_factory_start = true;
+ mode = "FACTORY_MODE";
+ } else {
+ pr_warn("%s:%s Wrong command\n", DEV_NAME, __func__);
+ return count;
+ }
+
+ pr_info("%s:%s apo factory=%s\n", DEV_NAME, __func__, mode);
+
+ return count;
+}
+#endif /* !CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK */
+
#ifdef CONFIG_LTE_VIA_SWITCH
static ssize_t max77693_muic_show_check_cpboot(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -1002,6 +1063,11 @@ static DEVICE_ATTR(otg_block, 0664,
max77693_muic_show_otg_block,
max77693_muic_set_otg_block);
#endif /* CONFIG_MACH_GC1 */
+#if !defined(CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK)
+static DEVICE_ATTR(apo_factory, 0664,
+ max77693_muic_show_apo_factory,
+ max77693_muic_set_apo_factory);
+#endif /* !CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK */
#ifdef CONFIG_LTE_VIA_SWITCH
static DEVICE_ATTR(check_cpboot, 0664,
max77693_muic_show_check_cpboot,
@@ -1020,6 +1086,9 @@ static struct attribute *max77693_muic_attributes[] = {
#if defined(CONFIG_MACH_GC1)
&dev_attr_otg_block.attr,
#endif /* CONFIG_MACH_GC1 */
+#if !defined(CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK)
+ &dev_attr_apo_factory.attr,
+#endif /* !CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK */
#ifdef CONFIG_LTE_VIA_SWITCH
&dev_attr_check_cpboot.attr,
#endif
@@ -1085,6 +1154,13 @@ static int max77693_muic_set_usb_path(struct max77693_muic_info *info, int path)
(0 << MICEN_SHIFT);
cntl1_msk = COMN1SW_MASK | COMP2SW_MASK | MICEN_MASK;
break;
+ case OPEN_USB_MODE:
+ dev_info(info->dev, "%s: OPEN_USB_MODE\n", __func__);
+ gpio_val = 0;
+ val = MAX77693_MUIC_CTRL1_BIN_0_000;
+ cntl1_val = (val << COMN1SW_SHIFT) | (val << COMP2SW_SHIFT);
+ cntl1_msk = COMN1SW_MASK | COMP2SW_MASK;
+ break;
default:
dev_warn(info->dev, "%s: invalid path(%d)\n", __func__, path);
return -EINVAL;
@@ -1415,6 +1491,7 @@ static int max77693_muic_attach_dock_type(struct max77693_muic_info *info,
if (mdata->dock_cb)
mdata->dock_cb(MAX77693_MUIC_DOCK_CARDOCK);
break;
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK)
case ADC_SMARTDOCK:
if (info->cable_type == CABLE_TYPE_SMARTDOCK_MUIC) {
dev_info(info->dev, "%s: duplicated(SmartDock)\n",
@@ -1423,7 +1500,17 @@ static int max77693_muic_attach_dock_type(struct max77693_muic_info *info,
}
dev_info(info->dev, "%s:SmartDock\n", __func__);
info->cable_type = CABLE_TYPE_SMARTDOCK_MUIC;
- path = AP_USB_MODE;
+
+ if (info->is_usb_ready) {
+ pr_info("%s:%s usb is ready, D+,D- line(AP_USB)\n",
+ DEV_NAME, __func__);
+ path = AP_USB_MODE;
+ } else {
+ pr_info("%s:%s usb not ready yet, D+,D- line(Open)\n",
+ DEV_NAME, __func__);
+ path = OPEN_USB_MODE;
+ }
+
max77693_muic_set_charging_type(info, false);
msleep(40);
#ifdef CONFIG_EXTCON
@@ -1436,6 +1523,36 @@ static int max77693_muic_attach_dock_type(struct max77693_muic_info *info,
if (mdata->dock_cb)
mdata->dock_cb(MAX77693_MUIC_DOCK_SMARTDOCK);
break;
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK */
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
+ case ADC_AUDIODOCK:
+ if (info->cable_type == CABLE_TYPE_AUDIODOCK_MUIC) {
+ pr_info("%s:%s duplicated(AudioDock)\n", DEV_NAME,
+ __func__);
+ return 0;
+ }
+ pr_info("%s:%s AudioDock\n", DEV_NAME, __func__);
+ info->cable_type = CABLE_TYPE_AUDIODOCK_MUIC;
+
+ if (info->is_usb_ready) {
+ pr_info("%s:%s usb is ready, D+,D- line(AP_USB)\n",
+ DEV_NAME, __func__);
+ path = AP_USB_MODE;
+ } else {
+ pr_info("%s:%s usb not ready yet, D+,D- line(Open)\n",
+ DEV_NAME, __func__);
+ path = OPEN_USB_MODE;
+ }
+
+ max77693_muic_set_charging_type(info, false);
+
+ if (mdata->usb_cb && info->is_usb_ready)
+ mdata->usb_cb(USB_POWERED_HOST_ATTACHED);
+
+ if (mdata->dock_cb)
+ mdata->dock_cb(MAX77693_MUIC_DOCK_AUDIODOCK);
+ break;
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
default:
dev_info(info->dev, "%s: should not reach here(0x%x)\n",
__func__, adc);
@@ -1802,54 +1919,89 @@ void powered_otg_control(int enable)
max77693_powered_otg_control(gInfo, enable);
}
-#if defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
-#define BAT_PSY_NAME "battery"
-void max77693_muic_attach_audio_dock(void)
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK)
+static void max77693_muic_set_cddelay(struct max77693_muic_info *info)
{
- struct max77693_muic_info *info = gInfo;
- struct max77693_muic_data *mdata = info->muic_data;
- struct power_supply *psy = power_supply_get_by_name(BAT_PSY_NAME);
- union power_supply_propval value;
+ u8 cdetctrl1;
+ int ret = 0;
- switch (info->cable_type) {
-#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK)
- case CABLE_TYPE_SMARTDOCK_MUIC:
- case CABLE_TYPE_SMARTDOCK_TA_MUIC:
- case CABLE_TYPE_SMARTDOCK_USB_MUIC:
- pr_info("%s:%s= SmartDock connected, ignore.\n", __FILE__,
+ ret = max77693_read_reg(info->max77693->muic,
+ MAX77693_MUIC_REG_CDETCTRL1, &cdetctrl1);
+
+ pr_info("%s:%s read CDETCTRL1=0x%x, ret=%d\n", DEV_NAME, __func__,
+ cdetctrl1, ret);
+
+ if ((cdetctrl1 & 0x10) == 0x10) {
+ pr_info("%s:%s CDDelay already setted, return\n", DEV_NAME,
__func__);
return;
-#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK */
- default:
- break;
}
- dev_info(info->dev, "%s:AudioDock\n", __func__);
+ cdetctrl1 |= 0x10;
- info->cable_type = CABLE_TYPE_AUDIODOCK_MUIC;
+ ret = max77693_write_reg(info->max77693->muic,
+ MAX77693_MUIC_REG_CDETCTRL1, cdetctrl1);
- max77693_otg_control(info, 0);
+ pr_info("%s:%s write CDETCTRL1=0x%x, ret=%d\n", DEV_NAME,
+ __func__, cdetctrl1, ret);
+}
- if (mdata->dock_cb)
- mdata->dock_cb(MAX77693_MUIC_DOCK_AUDIODOCK);
+static void max77693_muic_clear_cddelay(struct max77693_muic_info *info)
+{
+ u8 cdetctrl1;
+ int ret = 0;
+
+ ret = max77693_read_reg(info->max77693->muic,
+ MAX77693_MUIC_REG_CDETCTRL1, &cdetctrl1);
+
+ pr_info("%s:%s read CDETCTRL1=0x%x, ret=%d\n", DEV_NAME, __func__,
+ cdetctrl1, ret);
- if (!psy || !psy->set_property) {
- pr_err("%s: fail to get %s psy\n", __func__, BAT_PSY_NAME);
+ if ((cdetctrl1 & 0x10) == 0x0) {
+ pr_info("%s:%s CDDelay already cleared, return\n", DEV_NAME,
+ __func__);
return;
}
- psy->set_property(psy, POWER_SUPPLY_PROP_STATUS, &value);
+ cdetctrl1 &= ~(0x10);
+
+ ret = max77693_write_reg(info->max77693->muic,
+ MAX77693_MUIC_REG_CDETCTRL1, cdetctrl1);
+
+ pr_info("%s:%s write CDETCTRL1=0x%x, ret=%d\n", DEV_NAME,
+ __func__, cdetctrl1, ret);
}
-#endif /* CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
-#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK)
static void max77693_muic_detach_smart_dock(struct max77693_muic_info *info)
{
struct max77693_muic_data *mdata = info->muic_data;
+ enum cable_type_muic tmp_cable_type = info->cable_type;
pr_info("%s:%s\n", DEV_NAME, __func__);
- switch (info->cable_type) {
+ if (info->cable_type != CABLE_TYPE_SMARTDOCK_MUIC &&
+ info->cable_type != CABLE_TYPE_SMARTDOCK_TA_MUIC &&
+ info->cable_type != CABLE_TYPE_SMARTDOCK_USB_MUIC) {
+ pr_info("%s:%s cable_type is not SMARTDOCK\n", DEV_NAME,
+ __func__);
+ return;
+ }
+
+ if (mdata->dock_cb)
+ mdata->dock_cb(MAX77693_MUIC_DOCK_DETACHED);
+
+ info->cable_type = CABLE_TYPE_NONE_MUIC;
+
+ max77693_muic_set_charging_type(info, false);
+#ifdef CONFIG_EXTCON
+ if (info->edev && info->is_mhl_ready)
+ extcon_set_cable_state(info->edev, "MHL", false);
+#else
+ if (mdata->mhl_cb && info->is_mhl_ready)
+ mdata->mhl_cb(MAX77693_MUIC_DETACHED);
+#endif
+
+ switch (tmp_cable_type) {
case CABLE_TYPE_SMARTDOCK_TA_MUIC:
pr_info("%s:%s SMARTDOCK+TA\n", DEV_NAME, __func__);
@@ -1863,29 +2015,16 @@ static void max77693_muic_detach_smart_dock(struct max77693_muic_info *info)
mdata->usb_cb(USB_CABLE_DETACHED);
break;
case CABLE_TYPE_SMARTDOCK_MUIC:
+ /* clear CDDelay 500ms */
+ max77693_muic_clear_cddelay(info);
pr_info("%s:%s SMARTDOCK\n", DEV_NAME, __func__);
break;
default:
- pr_info("%s:%s cable_type is not SMARTDOCK\n", DEV_NAME,
+ pr_warn("%s:%s should not reach here!\n", DEV_NAME,
__func__);
return;
break;
}
-
- info->cable_type = CABLE_TYPE_NONE_MUIC;
-
- if (mdata->dock_cb) {
- mdata->dock_cb(MAX77693_MUIC_DOCK_DETACHED);
- msleep(20);
- }
- max77693_muic_set_charging_type(info, false);
-#ifdef CONFIG_EXTCON
- if (info->edev && info->is_mhl_ready)
- extcon_set_cable_state(info->edev, "MHL", false);
-#else
- if (mdata->mhl_cb && info->is_mhl_ready)
- mdata->mhl_cb(MAX77693_MUIC_DETACHED);
-#endif
}
static void max77693_muic_attach_smart_dock(struct max77693_muic_info *info,
@@ -1896,6 +2035,8 @@ static void max77693_muic_attach_smart_dock(struct max77693_muic_info *info,
switch (info->cable_type) {
case CABLE_TYPE_SMARTDOCK_MUIC:
if (chgtyp == CHGTYP_DEDICATED_CHGR) {
+ /* clear CDDelay 500ms */
+ max77693_muic_clear_cddelay(info);
pr_info("%s:%s SMART_DOCK+TA=OTG Enable\n", DEV_NAME,
__func__);
@@ -1904,6 +2045,8 @@ static void max77693_muic_attach_smart_dock(struct max77693_muic_info *info,
info->cable_type = CABLE_TYPE_SMARTDOCK_TA_MUIC;
} else if (chgtyp == CHGTYP_USB) {
+ /* clear CDDelay 500ms */
+ max77693_muic_clear_cddelay(info);
pr_info("%s:%s SMART_DOCK+USB=USB Enable\n", DEV_NAME,
__func__);
@@ -1940,7 +2083,17 @@ static void max77693_muic_attach_smart_dock(struct max77693_muic_info *info,
pr_info("%s:%s SMART_DOCK+vbvolt=chgdetrun\n",
DEV_NAME, __func__);
max77693_muic_attach_dock_type(info, adc);
+ if (chgtyp == CHGTYP_DEDICATED_CHGR ||
+ chgtyp == CHGTYP_USB) {
+ pr_info("%s:%s SMART_DOCK+(TA or USB)="\
+ "Recursive call to attach oneshot\n",
+ DEV_NAME, __func__);
+ max77693_muic_attach_smart_dock(info, adc,
+ vbvolt, chgtyp);
+ }
} else {
+ /* set CDDelay 500ms */
+ max77693_muic_set_cddelay(info);
dev_warn(info->dev, "no vbus in SAMRTDOCK\n");
}
break;
@@ -1948,14 +2101,34 @@ static void max77693_muic_attach_smart_dock(struct max77693_muic_info *info,
}
#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK */
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
+static void max77693_muic_detach_audio_dock(struct max77693_muic_info *info)
+{
+ struct max77693_muic_data *mdata = info->muic_data;
+
+ pr_info("%s:%s AUDIODOCK\n", DEV_NAME, __func__);
+
+ info->cable_type = CABLE_TYPE_NONE_MUIC;
+
+ max77693_muic_set_charging_type(info, false);
+
+ if (mdata->dock_cb)
+ mdata->dock_cb(MAX77693_MUIC_DOCK_DETACHED);
+
+ if (mdata->usb_cb && info->is_usb_ready)
+ mdata->usb_cb(USB_POWERED_HOST_DETACHED);
+}
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
+
static int max77693_muic_handle_attach(struct max77693_muic_info *info,
u8 status1, u8 status2, int irq)
{
struct max77693_muic_data *mdata = info->muic_data;
- u8 adc, vbvolt, chgtyp, chgdetrun, adc1k, dxovp;
+ u8 adc, adclow, vbvolt, chgtyp, chgdetrun, adc1k, dxovp;
int ret = 0;
adc = status1 & STATUS1_ADC_MASK;
+ adclow = status1 & STATUS1_ADCLOW_MASK;
adc1k = status1 & STATUS1_ADC1K_MASK;
chgtyp = status2 & STATUS2_CHGTYP_MASK;
vbvolt = status2 & STATUS2_VBVOLT_MASK;
@@ -1966,6 +2139,18 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
__func__, status1, status2, info->cable_type);
switch (info->cable_type) {
+ case CABLE_TYPE_OTG_MUIC:
+ if (!!adclow) {
+ pr_warn("%s:%s assume OTG detach\n", DEV_NAME,
+ __func__);
+ info->cable_type = CABLE_TYPE_NONE_MUIC;
+
+ max77693_muic_set_charging_type(info, false);
+
+ if (mdata->usb_cb && info->is_usb_ready)
+ mdata->usb_cb(USB_OTGHOST_DETACHED);
+ }
+ break;
case CABLE_TYPE_JIG_UART_OFF_MUIC:
case CABLE_TYPE_JIG_UART_OFF_VB_MUIC:
/* Workaround for Factory mode.
@@ -1984,6 +2169,13 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
&& info->max77693->pmic_rev >= MAX77693_REV_PASS2)
max77693_muic_handle_jig_uart(info, vbvolt);
+#if !defined(CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK)
+ if (info->is_factory_start) {
+ pr_info("%s:%s factory start, keep attach\n",
+ DEV_NAME, __func__);
+ break;
+ }
+#endif /* !CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK */
dev_warn(info->dev, "%s: abandon ADC\n", __func__);
return 0;
}
@@ -1994,7 +2186,6 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
info->cable_type = CABLE_TYPE_NONE_MUIC;
}
break;
-
case CABLE_TYPE_DESKDOCK_MUIC:
if (adc != ADC_DESKDOCK) {
dev_warn(info->dev, "%s: assume deskdock detach\n",
@@ -2007,7 +2198,6 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
mdata->dock_cb(MAX77693_MUIC_DOCK_DETACHED);
}
break;
-
case CABLE_TYPE_CARDOCK_MUIC:
if (adc != ADC_CARDOCK) {
dev_warn(info->dev, "%s: assume cardock detach\n",
@@ -2020,6 +2210,19 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
mdata->dock_cb(MAX77693_MUIC_DOCK_DETACHED);
}
break;
+#if !defined(CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK)
+ case CABLE_TYPE_JIG_UART_ON_MUIC:
+ if ((adc != ADC_JIG_UART_ON) &&
+ info->is_factory_start) {
+ pr_warn("%s:%s assume jig uart on detach\n",
+ DEV_NAME, __func__);
+ info->cable_type = CABLE_TYPE_NONE_MUIC;
+
+ if (mdata->dock_cb)
+ mdata->dock_cb(MAX77693_MUIC_DOCK_DETACHED);
+ }
+ break;
+#endif /* !CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK */
#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK)
case CABLE_TYPE_SMARTDOCK_MUIC:
case CABLE_TYPE_SMARTDOCK_TA_MUIC:
@@ -2029,26 +2232,21 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
__func__);
max77693_muic_detach_smart_dock(info);
+
+ info->is_adc_open_prev = false;
}
break;
#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK */
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
case CABLE_TYPE_AUDIODOCK_MUIC:
- if (adc != ADC_GND) {
+ if ((adc != ADC_AUDIODOCK) || (!vbvolt)) {
dev_warn(info->dev, "%s: assume audiodock detach\n",
__func__);
- info->cable_type = CABLE_TYPE_NONE_MUIC;
-
- max77693_muic_set_charging_type(info, false);
- info->is_adc_open_prev = false;
- if (mdata->usb_cb && info->is_usb_ready)
- mdata->usb_cb(USB_OTGHOST_DETACHED);
-
- if (mdata->dock_cb)
- mdata->dock_cb(MAX77693_MUIC_DOCK_DETACHED);
+ max77693_muic_detach_audio_dock(info);
}
break;
-
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
default:
break;
}
@@ -2065,6 +2263,10 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
"%s: Ignore irq:%d at MHL detection\n",
__func__, irq);
if (vbvolt) {
+ if (info->cable_type == CABLE_TYPE_MHL_MUIC
+ && chgtyp == CHGTYP_USB)
+ info->cable_type = CABLE_TYPE_MHL_VB_MUIC;
+
dev_info(info->dev, "%s: call charger_cb(%d)"
, __func__, vbvolt);
max77693_muic_set_charging_type(info, false);
@@ -2084,13 +2286,6 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
switch (adc) {
case ADC_GND:
if (chgtyp == CHGTYP_NO_VOLTAGE) {
-#if defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
- if (info->cable_type == CABLE_TYPE_AUDIODOCK_MUIC) {
- pr_info("%s:%s audio_dock attached, ignore\n",
- DEV_NAME, __func__);
- break;
- }
-#endif /* CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
if (info->cable_type == CABLE_TYPE_OTG_MUIC) {
dev_info(info->dev,
"%s: duplicated(OTG)\n", __func__);
@@ -2116,6 +2311,12 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
max77693_muic_attach_smart_dock(info, adc, vbvolt, chgtyp);
break;
#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK */
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
+ case ADC_AUDIODOCK:
+ if (!!vbvolt)
+ max77693_muic_attach_dock_type(info, adc);
+ break;
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
case ADC_JIG_UART_OFF:
max77693_muic_handle_jig_uart(info, vbvolt);
#if defined(CONFIG_MACH_T0_CHN_CMCC)
@@ -2135,7 +2336,23 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
mdata->jig_state(true);
break;
case ADC_DESKDOCK:
+ max77693_muic_attach_dock_type(info, adc);
+ if (chgtyp == CHGTYP_USB ||
+ chgtyp == CHGTYP_DOWNSTREAM_PORT ||
+ chgtyp == CHGTYP_DEDICATED_CHGR ||
+ chgtyp == CHGTYP_500MA || chgtyp == CHGTYP_1A)
+ ret = max77693_muic_set_charging_type(info, false);
+ else if (chgtyp == CHGTYP_NO_VOLTAGE && !chgdetrun)
+ ret = max77693_muic_set_charging_type(info, !vbvolt);
+ /* For MAX77693 IC doesn`t occur chgtyp IRQ
+ * because of audio noise prevention.
+ * So, If below condition is set,
+ * we do charging at CARDOCK.
+ */
+ break;
+ /* ADC_CARDOCK == ADC_JIG_UART_ON */
case ADC_CARDOCK:
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK)
max77693_muic_attach_dock_type(info, adc);
if (chgtyp == CHGTYP_USB ||
chgtyp == CHGTYP_DOWNSTREAM_PORT ||
@@ -2149,7 +2366,29 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
* So, If below condition is set,
* we do charging at CARDOCK.
*/
- break;
+#else
+ /* because of change FACTORY CPOriented to APOriented,
+ * at manufacture need AP wake-up method. write apo_factory
+ * "FACTORY_START" is set is_factory_start true
+ * and write apo_factory "FACTORY_END" is set
+ * is_factory_start false.
+ */
+ if (info->is_factory_start) {
+ if (info->cable_type == CABLE_TYPE_JIG_UART_ON_MUIC) {
+ pr_info("%s:%s duplicated(JIG_UART_ON)\n",
+ DEV_NAME, __func__);
+ return 0;
+ }
+ pr_info("%s:%s JIG_UART_ON\n", DEV_NAME, __func__);
+ info->cable_type = CABLE_TYPE_JIG_UART_ON_MUIC;
+
+ if (mdata->dock_cb)
+ mdata->dock_cb(MAX77693_MUIC_DOCK_DESKDOCK);
+
+ return 0;
+ }
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK */
+ break;
#if defined(CONFIG_MUIC_DET_JACK)
case ADC_MHL_OR_SENDEND:
case ADC_DOCK_VOL_UP:
@@ -2229,14 +2468,6 @@ static int max77693_muic_handle_attach(struct max77693_muic_info *info,
break;
}
-#ifdef CONFIG_FAST_BOOT
- if ((info->cable_type == CABLE_TYPE_TA_MUIC) && (fake_shut_down)) {
- pr_info("%s: Resetting the device in fake shutdown mode"\
- "(TA inserted !!!)\n", __func__);
- kernel_power_off();
- }
-#endif
-
return ret;
}
@@ -2288,6 +2519,11 @@ static int max77693_muic_handle_detach(struct max77693_muic_info *info, int irq)
#endif /* CONFIG_USBHUB_USB3803 */
info->previous_key = DOCK_KEY_NONE;
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK)
+ /* clear CDDelay 500ms */
+ max77693_muic_clear_cddelay(info);
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK */
+
if (info->cable_type == CABLE_TYPE_NONE_MUIC) {
dev_info(info->dev, "%s: duplicated(NONE)\n", __func__);
return 0;
@@ -2305,18 +2541,6 @@ static int max77693_muic_handle_detach(struct max77693_muic_info *info, int irq)
if (mdata->usb_cb && info->is_usb_ready)
mdata->usb_cb(USB_OTGHOST_DETACHED);
break;
-
- case CABLE_TYPE_AUDIODOCK_MUIC:
- dev_info(info->dev, "%s: AUDIO\n", __func__);
- info->cable_type = CABLE_TYPE_NONE_MUIC;
-
- if (mdata->usb_cb && info->is_usb_ready)
- mdata->usb_cb(USB_OTGHOST_DETACHED);
-
- if (mdata->dock_cb)
- mdata->dock_cb(MAX77693_MUIC_DOCK_DETACHED);
- break;
-
case CABLE_TYPE_USB_MUIC:
case CABLE_TYPE_JIG_USB_OFF_MUIC:
case CABLE_TYPE_JIG_USB_ON_MUIC:
@@ -2377,8 +2601,18 @@ static int max77693_muic_handle_detach(struct max77693_muic_info *info, int irq)
info->cable_type = CABLE_TYPE_TA_MUIC;
break;
case CABLE_TYPE_JIG_UART_ON_MUIC:
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK)
dev_info(info->dev, "%s: JIG UART/BOOTON\n", __func__);
info->cable_type = CABLE_TYPE_NONE_MUIC;
+#else
+ if (info->is_factory_start) {
+ pr_info("%s:%s JIG_UART_ON\n", DEV_NAME, __func__);
+ info->cable_type = CABLE_TYPE_NONE_MUIC;
+
+ if (mdata->dock_cb)
+ mdata->dock_cb(MAX77693_MUIC_DOCK_DETACHED);
+ }
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK */
break;
case CABLE_TYPE_JIG_UART_OFF_MUIC:
dev_info(info->dev, "%s: JIG UART/BOOTOFF\n", __func__);
@@ -2391,6 +2625,11 @@ static int max77693_muic_handle_detach(struct max77693_muic_info *info, int irq)
max77693_muic_detach_smart_dock(info);
break;
#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK */
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
+ case CABLE_TYPE_AUDIODOCK_MUIC:
+ max77693_muic_detach_audio_dock(info);
+ break;
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
case CABLE_TYPE_JIG_UART_OFF_VB_MUIC:
dev_info(info->dev, "%s: JIG UART/OFF/VB\n", __func__);
info->cable_type = CABLE_TYPE_NONE_MUIC;
@@ -2478,7 +2717,7 @@ static int max77693_muic_filter_dev(struct max77693_muic_info *info,
vbvolt = status2 & STATUS2_VBVOLT_MASK;
dxovp = status2 & STATUS2_DXOVP_MASK;
- dev_info(info->dev, "adc:%x adcerr:%x chgtyp:%x vb:%x dxovp:%x cable_type:%x\n",
+ dev_info(info->dev, "adc:%x adcerr:%x chgtyp:%x vb:%x dxovp:%x cable_type:%d\n",
adc, adcerr, chgtyp, vbvolt, dxovp, info->cable_type);
#if !defined(CONFIG_MUIC_MAX77693_SEPARATE_MHL_PORT)
@@ -2513,10 +2752,11 @@ static int max77693_muic_filter_dev(struct max77693_muic_info *info,
case ADC_MHL ... (ADC_SMARTDOCK - 1):
case (ADC_OPEN - 1):
#endif /* !CONFIG_MUIC_DET_JACK */
- case (ADC_SMARTDOCK + 1) ... (ADC_CEA936ATYPE1_CHG - 1):
-#if !defined(CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK)
- case ADC_CARDOCK:
-#endif /* CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK */
+ case (ADC_SMARTDOCK + 1):
+#if !defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
+ case ADC_AUDIODOCK:
+#endif /* !CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
+ case (ADC_AUDIODOCK + 1) ... (ADC_CEA936ATYPE1_CHG - 1):
#endif /* CONFIG_MACH_GC1 */
dev_warn(info->dev, "%s: unsupported ADC(0x%02x)\n",
__func__, adc);
@@ -2682,6 +2922,87 @@ do { \
} \
} while (0)
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK) ||\
+ defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
+static void max77693_muic_dock_detect(struct work_struct *work)
+{
+ struct max77693_muic_info *info =
+ container_of(work, struct max77693_muic_info, dock_work.work);
+ struct i2c_client *client = info->muic;
+ u8 status[2];
+ int ret;
+ u8 cntl1_val;
+ u8 adc, adclow, adcerr, adc1k, chgtyp, vbvolt, dxovp;
+
+ mutex_lock(&info->mutex);
+ ret = max77693_read_reg(client, MAX77693_MUIC_REG_CTRL1, &cntl1_val);
+ pr_info("%s:%s CONTROL1:%x\n", DEV_NAME, __func__, cntl1_val);
+
+ ret = max77693_bulk_read(client, MAX77693_MUIC_REG_STATUS1, 2, status);
+ if (ret) {
+ pr_err("%s:%s fail to read muic reg(%d)\n", DEV_NAME, __func__,
+ ret);
+ goto end;
+ }
+
+ pr_info("%s:%s STATUS1:0x%x, 2:0x%x\n", DEV_NAME, __func__, status[0],
+ status[1]);
+
+ adc = status[0] & STATUS1_ADC_MASK;
+ adclow = status[0] & STATUS1_ADCLOW_MASK;
+ adcerr = status[0] & STATUS1_ADCERR_MASK;
+ adc1k = status[0] & STATUS1_ADC1K_MASK;
+ chgtyp = status[1] & STATUS2_CHGTYP_MASK;
+ vbvolt = status[1] & STATUS2_VBVOLT_MASK;
+ dxovp = status[1] & STATUS2_DXOVP_MASK;
+
+ pr_info("%s:%s adc:%x adcerr:%x chgtyp:%x vb:%x dxovp:%x"\
+ " cable_type:%d\n", DEV_NAME, __func__, adc, adcerr, chgtyp,
+ vbvolt, dxovp, info->cable_type);
+
+ if (adc1k) {
+ pr_info("%s:%s MHL attached, goto end\n", DEV_NAME, __func__);
+ goto end;
+ }
+
+ if (adcerr) {
+ pr_info("%s:%s ADC error, goto end\n", DEV_NAME, __func__);
+ goto end;
+ }
+
+ switch (adc) {
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK)
+ case ADC_SMARTDOCK:
+ pr_info("%s:%s Smart Dock\n", DEV_NAME, __func__);
+
+ if (vbvolt && !info->is_usb_ready) {
+ pr_info("%s:%s usb not ready yet, D+,D- line(Open)\n",
+ DEV_NAME, __func__);
+ max77693_muic_set_usb_path(info, OPEN_USB_MODE);
+ }
+ break;
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK */
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
+ case ADC_AUDIODOCK:
+ pr_info("%s:%s Audio Dock\n", DEV_NAME, __func__);
+
+ if (vbvolt && !info->is_usb_ready) {
+ pr_info("%s:%s usb not ready yet, D+,D- line(Open)\n",
+ DEV_NAME, __func__);
+ max77693_muic_set_usb_path(info, OPEN_USB_MODE);
+ }
+ break;
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
+ default:
+ break;
+ }
+
+end:
+ mutex_unlock(&info->mutex);
+}
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK ||
+ CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
+
static void max77693_muic_init_detect(struct work_struct *work)
{
struct max77693_muic_info *info =
@@ -2720,6 +3041,34 @@ static void max77693_muic_usb_detect(struct work_struct *work)
mdata->usb_cb(USB_OTGHOST_ATTACHED);
break;
case CABLE_TYPE_SMARTDOCK_MUIC:
+ pr_info("%s:%s now usb ready, turn "\
+ "D+,D- line to AP_USB\n", DEV_NAME,
+ __func__);
+ max77693_muic_set_usb_path(info, AP_USB_MODE);
+ break;
+ case CABLE_TYPE_SMARTDOCK_TA_MUIC:
+ pr_info("%s:%s now usb ready, turn "\
+ "D+,D- line to AP_USB\n", DEV_NAME,
+ __func__);
+ max77693_muic_set_usb_path(info, AP_USB_MODE);
+
+ mdata->usb_cb(USB_POWERED_HOST_ATTACHED);
+ break;
+ case CABLE_TYPE_SMARTDOCK_USB_MUIC:
+ pr_info("%s:%s now usb ready, turn "\
+ "D+,D- line to AP_USB\n", DEV_NAME,
+ __func__);
+ max77693_muic_set_usb_path(info, AP_USB_MODE);
+
+ mdata->usb_cb(USB_CABLE_ATTACHED);
+ break;
+ case CABLE_TYPE_AUDIODOCK_MUIC:
+ pr_info("%s:%s now usb ready, turn "\
+ "D+,D- line to AP_USB\n", DEV_NAME,
+ __func__);
+ max77693_muic_set_usb_path(info, AP_USB_MODE);
+
+ mdata->usb_cb(USB_POWERED_HOST_ATTACHED);
break;
default:
break;
@@ -2742,7 +3091,10 @@ static void max77693_muic_mhl_detect(struct work_struct *work)
info->is_mhl_ready = true;
if (info->cable_type == CABLE_TYPE_MHL_MUIC ||
- info->cable_type == CABLE_TYPE_MHL_VB_MUIC) {
+ info->cable_type == CABLE_TYPE_MHL_VB_MUIC ||
+ info->cable_type == CABLE_TYPE_SMARTDOCK_MUIC ||
+ info->cable_type == CABLE_TYPE_SMARTDOCK_TA_MUIC ||
+ info->cable_type == CABLE_TYPE_SMARTDOCK_USB_MUIC) {
#ifdef CONFIG_EXTCON
if (info->edev)
extcon_set_cable_state(info->edev, "MHL", true);
@@ -2945,6 +3297,9 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev)
#if defined(CONFIG_MACH_GC1)
info->is_otg_attach_blocked = false;
#endif /* CONFIG_MACH_GC1 */
+#if !defined(CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK)
+ info->is_factory_start = false;
+#endif /* !CONFIG_MUIC_MAX77693_SUPPORT_CAR_DOCK */
wake_lock_init(&info->muic_wake_lock, WAKE_LOCK_SUSPEND,
"muic wake lock");
@@ -3102,6 +3457,13 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev)
max77693_update_jig_state(info);
/* initial cable detection */
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK) ||\
+ defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
+ INIT_DELAYED_WORK(&info->dock_work, max77693_muic_dock_detect);
+ schedule_delayed_work(&info->dock_work, msecs_to_jiffies(50));
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK ||
+ CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
+
INIT_DELAYED_WORK(&info->init_work, max77693_muic_init_detect);
schedule_delayed_work(&info->init_work, msecs_to_jiffies(3000));
@@ -3143,6 +3505,11 @@ static int __devexit max77693_muic_remove(struct platform_device *pdev)
if (info) {
dev_info(info->dev, "func:%s\n", __func__);
input_unregister_device(info->input);
+#if defined(CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK) ||\
+ defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
+ cancel_delayed_work(&info->dock_work);
+#endif /* CONFIG_MUIC_MAX77693_SUPPORT_SMART_DOCK ||
+ CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
cancel_delayed_work(&info->init_work);
cancel_delayed_work(&info->usb_work);
cancel_delayed_work(&info->mhl_work);
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig
index 4283bc2eb46..2320c98cff5 100644
--- a/drivers/mmc/card/Kconfig
+++ b/drivers/mmc/card/Kconfig
@@ -81,3 +81,10 @@ config MMC_SELECTIVE_PACKED_CMD_POLICY
tristate "Change the condition of Pakced command"
help
Say Y here to change packed_cmd policy
+
+config MMC_CPRM
+ bool "Japan only CPRM MMC driver"
+ depends on MMC_BLOCK
+ default n
+ help
+ Japan only feature of CPRM MMC driver. \ No newline at end of file
diff --git a/drivers/mmc/card/Makefile b/drivers/mmc/card/Makefile
index a6efd4d85e7..fad6e00c3ca 100644
--- a/drivers/mmc/card/Makefile
+++ b/drivers/mmc/card/Makefile
@@ -1,10 +1,6 @@
#
# Makefile for MMC/SD card drivers
#
-ifeq ($(CONFIG_MMC_CPRM),y)
-EXTRA_CFLAGS += -I$(src)/cprm/softcprm
-EXTRA_CFLAGS += -I$(src)/cprm/include
-endif
obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
mmc_block-objs := block.o queue.o
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 70279622c91..f49e92cd616 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -60,6 +60,9 @@ MODULE_ALIAS("mmc:block");
#define MMC_IOCTL_GET_SECTOR_COUNT _IOR(MMC_IOCTL_BASE, 100, int)
#define MMC_IOCTL_GET_SECTOR_SIZE _IOR(MMC_IOCTL_BASE, 101, int)
#define MMC_IOCTL_GET_BLOCK_SIZE _IOR(MMC_IOCTL_BASE, 102, int)
+#define MMC_IOCTL_SET_RETRY_AKE_PROCESS _IOR(MMC_IOCTL_BASE, 104, int)
+
+static int cprm_ake_retry_flag;
#endif
#ifdef MOVI_DEBUG
@@ -329,6 +332,47 @@ out:
return ERR_PTR(err);
}
+struct scatterlist *mmc_blk_get_sg(struct mmc_card *card,
+ unsigned char *buf, int *sg_len, int size)
+{
+ struct scatterlist *sg;
+ struct scatterlist *sl;
+ int total_sec_cnt, sec_cnt;
+ int max_seg_size, len;
+
+ sl = kmalloc(sizeof(struct scatterlist) * card->host->max_segs, GFP_KERNEL);
+ if (!sl) {
+ return NULL;
+ }
+
+ sg = (struct scatterlist *)sl;
+ sg_init_table(sg, card->host->max_segs);
+
+ total_sec_cnt = size;
+ max_seg_size = card->host->max_seg_size;
+
+ len = 0;
+ while (total_sec_cnt) {
+ if (total_sec_cnt < max_seg_size)
+ sec_cnt = total_sec_cnt;
+ else
+ sec_cnt = max_seg_size;
+ sg_set_page(sg, virt_to_page(buf), sec_cnt, offset_in_page(buf));
+ buf = buf + sec_cnt;
+ total_sec_cnt = total_sec_cnt - sec_cnt;
+ len++;
+ if (total_sec_cnt == 0)
+ break;
+ sg = sg_next(sg);
+ }
+
+ if (sg)
+ sg_mark_end(sg);
+
+ *sg_len = len;
+
+ return sl;
+}
static int mmc_blk_ioctl_cmd(struct block_device *bdev,
struct mmc_ioc_cmd __user *ic_ptr)
{
@@ -338,7 +382,7 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct mmc_request mrq = {0};
- struct scatterlist sg;
+ struct scatterlist *sg = 0;
int err = 0;
/*
@@ -369,13 +413,22 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
cmd.arg = idata->ic.arg;
cmd.flags = idata->ic.flags;
+ if( cmd.opcode == MMC_IOC_CLOCK )
+ {
+ mmc_set_clock(card->host, cmd.arg);
+ err = 0;
+ goto cmd_done;
+ }
+
if (idata->buf_bytes) {
- data.sg = &sg;
- data.sg_len = 1;
+ int len;
data.blksz = idata->ic.blksz;
data.blocks = idata->ic.blocks;
- sg_init_one(data.sg, idata->buf, idata->buf_bytes);
+ sg = mmc_blk_get_sg(card, idata->buf, &len, idata->buf_bytes);
+
+ data.sg = sg;
+ data.sg_len = len;
if (idata->ic.write_flag)
data.flags = MMC_DATA_WRITE;
@@ -456,6 +509,9 @@ cmd_rel_host:
cmd_done:
if (md)
mmc_blk_put(md);
+ if (sg)
+ kfree(sg);
+
kfree(idata->buf);
kfree(idata);
return err;
@@ -467,6 +523,8 @@ static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
#ifdef MMC_ENABLE_CPRM
struct mmc_blk_data *md = bdev->bd_disk->private_data;
struct mmc_card *card = md->queue.card;
+ static int i;
+ static unsigned long temp_arg[16] = {0};
#endif
int ret = -EINVAL;
if (cmd == MMC_IOC_CMD)
@@ -476,6 +534,10 @@ static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
printk(KERN_DEBUG " %s ], %x ", __func__, cmd);
switch (cmd) {
+ case MMC_IOCTL_SET_RETRY_AKE_PROCESS:
+ cprm_ake_retry_flag = 1;
+ ret = 0;
+ break;
case MMC_IOCTL_GET_SECTOR_COUNT: {
int size = 0;
@@ -498,9 +560,54 @@ static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
struct cprm_request *req = (struct cprm_request *)arg;
printk(KERN_DEBUG "[%s]: cmd [%x]\n", __func__, cmd);
+ if (cmd == ACMD43) {
+ printk(KERN_DEBUG"storing acmd43 arg[%d] = %ul\n"
+ , i, (unsigned int)req->arg);
+ temp_arg[i] = req->arg;
+ i++;
+ if(i >= 16){
+ printk(KERN_DEBUG"reset acmd43 i = %d\n",
+ i);
+ i = 0;
+ }
+ }
+
+
+ if (cmd == ACMD45 && cprm_ake_retry_flag == 1) {
+ cprm_ake_retry_flag = 0;
+ printk(KERN_DEBUG"ACMD45.. I'll call ACMD43 and ACMD44 first\n");
+
+ for (i = 0; i < 16; i++) {
+ printk(KERN_DEBUG"calling ACMD43 with arg[%d] = %ul\n",
+ i, (unsigned int)temp_arg[i]);
+ if (stub_sendcmd(card,
+ ACMD43, temp_arg[i],
+ 512, NULL) < 0) {
+
+ printk(KERN_DEBUG"error ACMD43 %d\n", i);
+ return -EINVAL;
+ }
+ }
+
+
+ printk(KERN_DEBUG"calling ACMD44\n");
+ if (stub_sendcmd(card, ACMD44, 0, 8, NULL) < 0)
+ {
+
+ printk(KERN_DEBUG"error in ACMD44 %d\n",
+ i);
+ return -EINVAL;
+ }
+
+ }
return stub_sendcmd(card, req->cmd, req->arg, \
req->len, req->buff);
}
+ break;
+
+ default:
+ printk(KERN_DEBUG"%s: Invalid ioctl command\n", __func__);
+ break;
}
#endif
return ret;
@@ -2372,9 +2479,6 @@ static int mmc_blk_probe(struct mmc_card *card)
md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
cap_str, md->read_only ? "(ro)" : "");
- if (mmc_blk_alloc_parts(card, md))
- goto out;
-
mmc_set_drvdata(card, md);
mmc_fixup_device(card, blk_fixups);
diff --git a/drivers/mmc/card/cprmdrv_samsung.c b/drivers/mmc/card/cprmdrv_samsung.c
index 6f64a7fa2d3..81b430c8bf9 100644
--- a/drivers/mmc/card/cprmdrv_samsung.c
+++ b/drivers/mmc/card/cprmdrv_samsung.c
@@ -1,4 +1,17 @@
-
+/* drivers/mmc/cprmdrv_samsung.c
+ *
+ * Copyright 2010 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
#include <linux/mmc/core.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -54,7 +67,6 @@ static int CPRM_CMD_SecureRW(struct mmc_card *card,
struct mmc_command cmd;
struct mmc_command stop;
struct mmc_data data;
- unsigned int timeout_us;
struct scatterlist sg;
@@ -91,17 +103,8 @@ static int CPRM_CMD_SecureRW(struct mmc_card *card,
memset(&data, 0, sizeof(struct mmc_data));
- data.timeout_ns = card->csd.tacc_ns * 100;
- data.timeout_clks = card->csd.tacc_clks * 100;
-
- timeout_us = data.timeout_ns / 1000;
- timeout_us += data.timeout_clks * 1000 /
- (card->host->ios.clock / 1000);
-
- if (timeout_us > 100000) {
data.timeout_ns = 100000000;
data.timeout_clks = 0;
- }
#if defined(CONFIG_TARGET_LOCALE_NTT)
data.timeout_ns = 100000000;
@@ -178,7 +181,6 @@ static int CPRM_CMD_SecureMultiRW(struct mmc_card *card,
struct mmc_command cmd;
struct mmc_command stop;
struct mmc_data data;
- unsigned int timeout_us;
unsigned long flags;
struct scatterlist sg;
@@ -212,17 +214,8 @@ static int CPRM_CMD_SecureMultiRW(struct mmc_card *card,
memset(&data, 0, sizeof(struct mmc_data));
- data.timeout_ns = card->csd.tacc_ns * 100;
- data.timeout_clks = card->csd.tacc_clks * 100;
-
- timeout_us = data.timeout_ns / 1000;
- timeout_us += data.timeout_clks * 1000 /
- (card->host->ios.clock / 1000);
-
- if (timeout_us > 100000) {
data.timeout_ns = 100000000;
data.timeout_clks = 0;
- }
#if defined(CONFIG_TARGET_LOCALE_NTT)
data.timeout_ns = 100000000;
diff --git a/drivers/mmc/card/cprmdrv_samsung.h b/drivers/mmc/card/cprmdrv_samsung.h
index b07dd6e7f6f..68fc7cb1fc2 100644
--- a/drivers/mmc/card/cprmdrv_samsung.h
+++ b/drivers/mmc/card/cprmdrv_samsung.h
@@ -1,3 +1,17 @@
+/* drivers/mmc/cprmdrv_samsung.h
+ *
+ * Copyright 2010 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
#ifndef __CPRM_API_SAMSUNG
#define __CPRM_API_SAMSUNG
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 3403f53a52d..506a4e35bd6 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -35,6 +35,27 @@
#endif
#endif
+/*
+ * If moviNAND VHX 4.41 device
+ * enable PON to force.
+ */
+#define CHECK_MOVI_VHX4_41 \
+ (card->ext_csd.rev == 5 && card->movi_fwver >= 0x1C)
+
+/*
+ * If moviNAND VHX 4.5 device
+ * enable PON to force.
+ */
+#define CHECK_MOVI_VHX4_5 \
+ (card->ext_csd.rev == 6 && card->movi_fwver >= 0x0A)
+
+#define CHECK_MOVI_PON_SUPPORT \
+ (card->cid.manfid == 0x15 && \
+ ext_csd[EXT_CSD_VENDOR_SPECIFIC_FIELD] & 0x2)
+
+#define CHECK_PON_ENABLE \
+ (card->ext_csd.feature_support & MMC_POWEROFF_NOTIFY_FEATURE)
+
static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
0, 0, 0, 0
@@ -333,6 +354,7 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd)
static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
{
int err = 0;
+ int movi_ver_check = 0;
BUG_ON(!card);
@@ -581,11 +603,49 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
}
if (card->ext_csd.rev >= 5) {
- /* enable discard feature if emmc is 4.41+ */
+ /* If moviNAND, run smart report */
+ if (card->cid.manfid == 0x15) {
+ card->host->card = card;
+ movi_ver_check = mmc_start_movi_smart(card);
+ }
+
+ /* enable discard feature if emmc is 4.41+ moviNand */
if ((ext_csd[EXT_CSD_VENDOR_SPECIFIC_FIELD + 0] & 0x1) &&
(card->cid.manfid == 0x15))
card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
+ /* enable PON feature if moviNAND VHX/VMX devices */
+ if (CHECK_MOVI_PON_SUPPORT) {
+ if ((movi_ver_check & MMC_MOVI_VER_VHX0) &&
+ (CHECK_MOVI_VHX4_41 ||
+ CHECK_MOVI_VHX4_5)) {
+ card->ext_csd.feature_support |=
+ MMC_POWEROFF_NOTIFY_FEATURE;
+ card->ext_csd.generic_cmd6_time = 100;
+ card->ext_csd.power_off_longtime = 600;
+ }
+ if (movi_ver_check & MMC_MOVI_VER_VMX0) {
+ card->ext_csd.feature_support |=
+ MMC_POWEROFF_NOTIFY_FEATURE;
+ }
+ pr_info("%s : %s PON feature : "
+ "%02x : %02x(%02x) : %08x\n",
+ mmc_hostname(card->host),
+ card->ext_csd.feature_support & MMC_POWEROFF_NOTIFY_FEATURE ?
+ "enable" : "disable",
+ movi_ver_check,
+ card->movi_fwver, ext_csd[82],
+ card->movi_fwdate);
+ }
+
+ /*
+ * enable discard feature if emmc is 4.41+ Toshiba eMMC 19nm
+ * Normally, emmc 4.5 use EXT_CSD[501]
+ */
+ if ((ext_csd[EXT_CSD_MAX_PACKED_READS] & 0x3F) &&
+ (card->cid.manfid == 0x11))
+ card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
+
/* check whether the eMMC card supports HPI */
if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) {
card->ext_csd.hpi = 1;
@@ -717,6 +777,7 @@ MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
MMC_DEV_ATTR(enhanced_area_offset, "%llu\n",
card->ext_csd.enhanced_area_offset);
MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
+MMC_DEV_ATTR(fwver, "%02x : %x\n", card->movi_fwver, card->movi_fwdate);
static struct attribute *mmc_std_attrs[] = {
&dev_attr_cid.attr,
@@ -732,6 +793,7 @@ static struct attribute *mmc_std_attrs[] = {
&dev_attr_serial.attr,
&dev_attr_enhanced_area_offset.attr,
&dev_attr_enhanced_area_size.attr,
+ &dev_attr_fwver.attr,
NULL,
};
@@ -1111,22 +1173,20 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
* set the notification byte in the ext_csd register of device
*/
if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) &&
- (card->ext_csd.rev >= 6)) {
+ ((card->ext_csd.rev >= 5) && CHECK_PON_ENABLE)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_POWER_OFF_NOTIFICATION,
EXT_CSD_POWER_ON,
card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;
- }
-
- if (!err && (host->caps2 & MMC_CAP2_POWEROFF_NOTIFY))
/*
* The err can be -EBADMSG or 0,
* so check for success and update the flag
*/
if (!err)
card->poweroff_notify_state = MMC_POWERED_ON;
+ }
/*
* Activate high speed (if supported)
@@ -1656,10 +1716,10 @@ int mmc_attach_mmc(struct mmc_host *host)
if (!strncmp(host->card->cid.prod_name, "VTU00M", 6) &&
(host->card->cid.prod_rev == 0xf1) &&
- (mmc_start_movi_smart(host->card) == 0x2))
+ (host->card->movi_fwdate == 0x20120413)) {
+ /* It needs host work-around codes */
host->card->movi_ops = 0x2;
- if (host->card->movi_ops == 0x2) {
err = mmc_start_movi_operation(host->card);
if (err) {
pr_warning("%s: movi operation is failed\n",
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 90085a3714a..3cec4507b93 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -677,41 +677,59 @@ static int mmc_movi_read_req(struct mmc_card *card,
return 0;
}
+#define MOVI_CONT_VHX0 0x56485830
+#define MOVI_CONT_VMX0 0x564D5830
+
int mmc_start_movi_smart(struct mmc_card *card)
{
- int err;
+ int ret;
u8 data_buf[512];
u32 date = 0;
+ u32 old_date = 0;
+ u32 movi_ver = 0;
- err = mmc_movi_cmd(card->host, 0xEFAC62EC);
- if (err)
- return err;
+ ret = mmc_movi_cmd(card->host, 0xEFAC62EC);
+ if (ret)
+ return ret;
- err = mmc_movi_cmd(card->host, 0x0000CCEE);
- if (err)
- return err;
+ ret = mmc_movi_cmd(card->host, 0x0000CCEE);
+ if (ret)
+ return ret;
- err = mmc_movi_read_req(card, (void *)data_buf, 0x1000, 1);
- if (err)
- return err;
+ ret = mmc_movi_read_req(card, (void *)data_buf, 0x1000, 1);
+ if (ret)
+ return ret;
- err = mmc_movi_cmd(card->host, 0xEFAC62EC);
- if (err)
- return err;
+ ret = mmc_movi_cmd(card->host, 0xEFAC62EC);
+ if (ret)
+ return ret;
- err = mmc_movi_cmd(card->host, 0x00DECCEE);
- if (err)
- return err;
+ ret = mmc_movi_cmd(card->host, 0x00DECCEE);
+ if (ret)
+ return ret;
+
+ movi_ver = ((data_buf[312] << 24) | (data_buf[313] << 16) |
+ (data_buf[314] << 8) | data_buf[315]);
+ if (movi_ver == MOVI_CONT_VMX0)
+ ret = MMC_MOVI_VER_VMX0;
+ else if (movi_ver == MOVI_CONT_VHX0)
+ ret = MMC_MOVI_VER_VHX0;
+ else
+ ret = 0x0;
date = ((data_buf[327] << 24) | (data_buf[326] << 16) |
(data_buf[325] << 8) | data_buf[324]);
- if (date != 0x20120413) {
- err = -1;
- return err;
- }
+ card->movi_fwver = data_buf[320];
+ card->movi_fwdate = date;
+
+ old_date = ((data_buf[351] << 24) | (data_buf[350] << 16) |
+ (data_buf[349] << 8) | data_buf[348]);
+
+ pr_info("%s : %02x : %02x : %08x : %x.\n", mmc_hostname(card->host),
+ ret, card->movi_fwver, card->movi_fwdate, old_date);
- return 0x2;
+ return ret;
}
EXPORT_SYMBOL_GPL(mmc_start_movi_smart);
diff --git a/drivers/usb/core/sec-dock.h b/drivers/usb/core/sec-dock.h
index 1521b67d685..73c4ea6be3a 100644
--- a/drivers/usb/core/sec-dock.h
+++ b/drivers/usb/core/sec-dock.h
@@ -9,9 +9,6 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-#if defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
-#include <linux/mfd/max77693.h>
-#endif /* CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
#include <linux/power_supply.h>
#define PSY_CHG_NAME "max77693-charger"
@@ -48,7 +45,6 @@ static void call_audiodock_notify(struct usb_device *dev)
id->idVendor == le16_to_cpu(dev->descriptor.idVendor) &&
id->idProduct == le16_to_cpu(dev->descriptor.idProduct)) {
dev_info(&dev->dev, "Audio Dock is connected!\n");
- max77693_muic_attach_audio_dock();
return;
}
}
diff --git a/include/linux/battery/samsung_battery.h b/include/linux/battery/samsung_battery.h
index f58c83964e8..2293fce5c95 100644
--- a/include/linux/battery/samsung_battery.h
+++ b/include/linux/battery/samsung_battery.h
@@ -115,6 +115,7 @@ struct battery_info {
unsigned int cable_type;
unsigned int cable_sub_type;
unsigned int cable_pwr_type;
+ int online_prop;
/* For SAMSUNG charge spec */
unsigned int vf_state;
@@ -205,6 +206,12 @@ extern bool is_jig_attached;
#undef EXTENDED_ONLINE_TYPE
#endif
+enum online_property {
+ ONLINE_PROP_UNKNOWN = 0,
+ ONLINE_PROP_AC,
+ ONLINE_PROP_USB,
+};
+
/* use 2step charge termination */
#if defined(CONFIG_MACH_T0)
#define USE_2STEP_TERM
@@ -269,7 +276,11 @@ enum status_full_type {
/* WORKAROUND: define audio dock current */
#define DOCK_TYPE_AUDIO_CURR 1000
+#if defined(CONFIG_MACH_T0)
#define DOCK_TYPE_SMART_NOTG_CURR 1700
+#else
+#define DOCK_TYPE_SMART_NOTG_CURR 1000
+#endif
#define DOCK_TYPE_SMART_OTG_CURR 1000
#define DOCK_TYPE_LOW_CURR 475
diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index 7a2c5360667..ad0ccf856d1 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -413,7 +413,7 @@ enum {
#if defined(CONFIG_SWITCH_DUAL_MODEM)
CP_ESC_USB_MODE,
#endif
-
+ OPEN_USB_MODE
};
enum {
diff --git a/include/linux/mfd/max77693.h b/include/linux/mfd/max77693.h
index 274693a86d7..dc26961e9ba 100644
--- a/include/linux/mfd/max77693.h
+++ b/include/linux/mfd/max77693.h
@@ -150,8 +150,4 @@ struct max77693_muic_data {
extern int max7693_muic_cp_usb_state(void);
#endif
-#if defined(CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK)
-extern void max77693_muic_attach_audio_dock(void);
-#endif /* CONFIG_MUIC_MAX77693_SUPPORT_OTG_AUDIO_DOCK */
-
#endif /* __LINUX_MFD_MAX77693_H */
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 5eb40a97cee..8cbcc95e6e8 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -94,6 +94,7 @@ struct mmc_ext_csd {
unsigned int feature_support;
#define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */
+#define MMC_POWEROFF_NOTIFY_FEATURE BIT(1) /* PON feature */
};
struct sd_scr {
@@ -244,8 +245,12 @@ struct mmc_card {
struct dentry *debugfs_root;
unsigned int movi_ops;
+ unsigned int movi_fwver;
+ unsigned int movi_fwdate;
};
+#define MMC_MOVI_VER_VHX0 (1<<4)
+#define MMC_MOVI_VER_VMX0 (1<<5)
/*
* The world is not perfect and supplies us with broken mmc/sdio devices.
* For at least some of these bugs we need a work-around.
diff --git a/include/linux/mmc/ioctl.h b/include/linux/mmc/ioctl.h
index 5baf2983a12..8f8204bdbce 100644
--- a/include/linux/mmc/ioctl.h
+++ b/include/linux/mmc/ioctl.h
@@ -50,5 +50,5 @@ struct mmc_ioc_cmd {
* is enforced per ioctl call. For larger data transfers, use the normal
* block device operations.
*/
-#define MMC_IOC_MAX_BYTES (512L * 256)
+#define MMC_IOC_MAX_BYTES (512L * 512)
#endif /* LINUX_MMC_IOCTL_H */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index bc047b448b0..ac13431d9f4 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -84,6 +84,8 @@
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
+#define MMC_IOC_CLOCK 120
+
static inline bool mmc_op_multi(u32 opcode)
{
return opcode == MMC_WRITE_MULTIPLE_BLOCK ||
diff --git a/mm/cma.c b/mm/cma.c
index 9d07750a4cd..2e5805b70dc 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -284,9 +284,15 @@ bool cma_is_registered_region(phys_addr_t start, size_t size)
{
struct cma_region *reg;
+ if (start + size <= start)
+ return false;
+
cma_foreach_region(reg) {
if ((start >= reg->start) &&
- ((start + size) <= (reg->start + reg->size)))
+ ((start + size) <= (reg->start + reg->size)) &&
+ (size <= reg->size) &&
+ (start < (reg->start + reg->size)))
+
return true;
}
return false;
diff --git a/mm/page_alloc-cma.c b/mm/page_alloc-cma.c
index 74cdf7d1351..fc675bd368b 100644
--- a/mm/page_alloc-cma.c
+++ b/mm/page_alloc-cma.c
@@ -6057,7 +6057,7 @@ static int __alloc_contig_migrate_range(unsigned long start, unsigned long end)
failed_pages[i][j] = NULL;
}
- migrate_prep_local();
+ migrate_prep();
while (pfn < end || !list_empty(&cc.migratepages)) {
if (fatal_signal_pending(current)) {
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index d1751539cab..63d1a5f576c 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -2766,7 +2766,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- bclk_rate = params_rate(params) * 4;
+ bclk_rate = params_rate(params) * 2;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
bclk_rate *= 16;