From cae93db3111a524c234397fc53b6a2fc51099528 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 31 Jan 2013 09:29:29 +0900 Subject: extcon: max8997: Make max8997_extcon_cable static 'max8997_extcon_cable' is used only in this file. Hence make it static. Signed-off-by: Sachin Kamat Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max8997.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index df9358e30814..7039541e837f 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -109,7 +109,7 @@ struct max8997_muic_info { struct extcon_dev *edev; }; -const char *max8997_extcon_cable[] = { +static const char *max8997_extcon_cable[] = { [0] = "USB", [1] = "USB-Host", [2] = "TA", -- cgit v1.2.3 From 6a462e1d007a6eecb18c44a2fef3ba4953a3f4b2 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 31 Jan 2013 09:30:00 +0900 Subject: extcon: max8997: Remove unreachable code 'break' after 'return' is never executed and hence can be deleted. Signed-off-by: Sachin Kamat Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max8997.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 7039541e837f..d16090ddd65a 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -289,7 +289,6 @@ static int max8997_muic_handle_charger_type_detach( break; default: return -EINVAL; - break; } return 0; -- cgit v1.2.3 From 45d4a4e6f5e5dcdd00b7c9d370cfb9694358e4e9 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 31 Jan 2013 09:31:47 +0900 Subject: extcon: max77693: Make max77693_extcon_cable static 'max77693_extcon_cable' is used only in this file. Hence make it static. Signed-off-by: Sachin Kamat Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max77693.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index ad6e9a466855..b70e3815c459 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -185,7 +185,7 @@ enum { _EXTCON_CABLE_NUM, }; -const char *max77693_extcon_cable[] = { +static const char *max77693_extcon_cable[] = { [EXTCON_CABLE_USB] = "USB", [EXTCON_CABLE_USB_HOST] = "USB-Host", [EXTCON_CABLE_TA] = "TA", -- cgit v1.2.3 From e3e5bc02d2365d3e09164fd9a559011399ca2a4f Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 12 Feb 2013 20:44:19 +0900 Subject: extcon: max8997: Move defined constant to header file This patch move defined constants to header file(max77693-private.h) because of mask/unmask selectively interrupt of MUIC device according to attribute of H/W board. Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max8997.c | 92 +++++++++++++------------------------ include/linux/mfd/max8997-private.h | 49 ++++++++++++++++++++ 2 files changed, 80 insertions(+), 61 deletions(-) diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index d16090ddd65a..0fb1d48b0741 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -30,51 +30,6 @@ #define DEV_NAME "max8997-muic" -/* MAX8997-MUIC STATUS1 register */ -#define STATUS1_ADC_SHIFT 0 -#define STATUS1_ADCLOW_SHIFT 5 -#define STATUS1_ADCERR_SHIFT 6 -#define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT) -#define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT) -#define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT) - -/* MAX8997-MUIC STATUS2 register */ -#define STATUS2_CHGTYP_SHIFT 0 -#define STATUS2_CHGDETRUN_SHIFT 3 -#define STATUS2_DCDTMR_SHIFT 4 -#define STATUS2_DBCHG_SHIFT 5 -#define STATUS2_VBVOLT_SHIFT 6 -#define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT) -#define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT) -#define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT) -#define STATUS2_DBCHG_MASK (0x1 << STATUS2_DBCHG_SHIFT) -#define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT) - -/* MAX8997-MUIC STATUS3 register */ -#define STATUS3_OVP_SHIFT 2 -#define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT) - -/* MAX8997-MUIC CONTROL1 register */ -#define COMN1SW_SHIFT 0 -#define COMP2SW_SHIFT 3 -#define COMN1SW_MASK (0x7 << COMN1SW_SHIFT) -#define COMP2SW_MASK (0x7 << COMP2SW_SHIFT) -#define SW_MASK (COMP2SW_MASK | COMN1SW_MASK) - -#define MAX8997_SW_USB ((1 << COMP2SW_SHIFT) | (1 << COMN1SW_SHIFT)) -#define MAX8997_SW_AUDIO ((2 << COMP2SW_SHIFT) | (2 << COMN1SW_SHIFT)) -#define MAX8997_SW_UART ((3 << COMP2SW_SHIFT) | (3 << COMN1SW_SHIFT)) -#define MAX8997_SW_OPEN ((0 << COMP2SW_SHIFT) | (0 << COMN1SW_SHIFT)) - -#define MAX8997_ADC_GROUND 0x00 -#define MAX8997_ADC_MHL 0x01 -#define MAX8997_ADC_JIG_USB_1 0x18 -#define MAX8997_ADC_JIG_USB_2 0x19 -#define MAX8997_ADC_DESKDOCK 0x1a -#define MAX8997_ADC_JIG_UART 0x1c -#define MAX8997_ADC_CARDOCK 0x1d -#define MAX8997_ADC_OPEN 0x1f - struct max8997_muic_irq { unsigned int irq; const char *name; @@ -109,17 +64,32 @@ struct max8997_muic_info { struct extcon_dev *edev; }; +enum { + EXTCON_CABLE_USB = 0, + EXTCON_CABLE_USB_HOST, + EXTCON_CABLE_TA, + EXTCON_CABLE_FAST_CHARGER, + EXTCON_CABLE_SLOW_CHARGER, + EXTCON_CABLE_CHARGE_DOWNSTREAM, + EXTCON_CABLE_MHL, + EXTCON_CABLE_DOCK_DESK, + EXTCON_CABLE_DOCK_CARD, + EXTCON_CABLE_JIG, + + _EXTCON_CABLE_NUM, +}; + static const char *max8997_extcon_cable[] = { - [0] = "USB", - [1] = "USB-Host", - [2] = "TA", - [3] = "Fast-charger", - [4] = "Slow-charger", - [5] = "Charge-downstream", - [6] = "MHL", - [7] = "Dock-desk", - [8] = "Dock-card", - [9] = "JIG", + [EXTCON_CABLE_USB] = "USB", + [EXTCON_CABLE_USB_HOST] = "USB-Host", + [EXTCON_CABLE_TA] = "TA", + [EXTCON_CABLE_FAST_CHARGER] = "Fast-charger", + [EXTCON_CABLE_SLOW_CHARGER] = "Slow-charger", + [EXTCON_CABLE_CHARGE_DOWNSTREAM] = "Charge-downstream", + [EXTCON_CABLE_MHL] = "MHL", + [EXTCON_CABLE_DOCK_DESK] = "Dock-Desk", + [EXTCON_CABLE_DOCK_CARD] = "Dock-Card", + [EXTCON_CABLE_JIG] = "JIG", NULL, }; @@ -132,8 +102,8 @@ static int max8997_muic_handle_usb(struct max8997_muic_info *info, if (usb_type == MAX8997_USB_HOST) { /* switch to USB */ ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, - attached ? MAX8997_SW_USB : MAX8997_SW_OPEN, - SW_MASK); + attached ? CONTROL1_SW_USB : CONTROL1_SW_OPEN, + CONTROL1_SW_MASK); if (ret) { dev_err(info->dev, "failed to update muic register\n"); goto out; @@ -163,8 +133,8 @@ static int max8997_muic_handle_dock(struct max8997_muic_info *info, /* switch to AUDIO */ ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, - attached ? MAX8997_SW_AUDIO : MAX8997_SW_OPEN, - SW_MASK); + attached ? CONTROL1_SW_AUDIO : CONTROL1_SW_OPEN, + CONTROL1_SW_MASK); if (ret) { dev_err(info->dev, "failed to update muic register\n"); goto out; @@ -192,8 +162,8 @@ static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, /* switch to UART */ ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, - attached ? MAX8997_SW_UART : MAX8997_SW_OPEN, - SW_MASK); + attached ? CONTROL1_SW_UART : CONTROL1_SW_OPEN, + CONTROL1_SW_MASK); if (ret) { dev_err(info->dev, "failed to update muic register\n"); goto out; diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index 6ae21bf47d64..acf42e960320 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h @@ -194,6 +194,55 @@ enum max8997_muic_reg { MAX8997_MUIC_REG_END = 0xf, }; +/* MAX8997-MUIC STATUS1 register */ +#define STATUS1_ADC_SHIFT 0 +#define STATUS1_ADCLOW_SHIFT 5 +#define STATUS1_ADCERR_SHIFT 6 +#define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT) +#define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT) +#define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT) + +/* MAX8997-MUIC STATUS2 register */ +#define STATUS2_CHGTYP_SHIFT 0 +#define STATUS2_CHGDETRUN_SHIFT 3 +#define STATUS2_DCDTMR_SHIFT 4 +#define STATUS2_DBCHG_SHIFT 5 +#define STATUS2_VBVOLT_SHIFT 6 +#define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT) +#define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT) +#define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT) +#define STATUS2_DBCHG_MASK (0x1 << STATUS2_DBCHG_SHIFT) +#define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT) + +/* MAX8997-MUIC STATUS3 register */ +#define STATUS3_OVP_SHIFT 2 +#define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT) + +/* MAX8997-MUIC CONTROL1 register */ +#define COMN1SW_SHIFT 0 +#define COMP2SW_SHIFT 3 +#define COMN1SW_MASK (0x7 << COMN1SW_SHIFT) +#define COMP2SW_MASK (0x7 << COMP2SW_SHIFT) +#define CONTROL1_SW_MASK (COMP2SW_MASK | COMN1SW_MASK) + +#define CONTROL1_SW_USB ((1 << COMP2SW_SHIFT) \ + | (1 << COMN1SW_SHIFT)) +#define CONTROL1_SW_AUDIO ((2 << COMP2SW_SHIFT) \ + | (2 << COMN1SW_SHIFT)) +#define CONTROL1_SW_UART ((3 << COMP2SW_SHIFT) \ + | (3 << COMN1SW_SHIFT)) +#define CONTROL1_SW_OPEN ((0 << COMP2SW_SHIFT) \ + | (0 << COMN1SW_SHIFT)) + +#define MAX8997_ADC_GROUND 0x00 +#define MAX8997_ADC_MHL 0x01 +#define MAX8997_ADC_JIG_USB_1 0x18 +#define MAX8997_ADC_JIG_USB_2 0x19 +#define MAX8997_ADC_DESKDOCK 0x1a +#define MAX8997_ADC_JIG_UART 0x1c +#define MAX8997_ADC_CARDOCK 0x1d +#define MAX8997_ADC_OPEN 0x1f + enum max8997_haptic_reg { MAX8997_HAPTIC_REG_GENERAL = 0x00, MAX8997_HAPTIC_REG_CONF1 = 0x01, -- cgit v1.2.3 From 07c70503a420d48402b3859e2c1c4c847a130a8b Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 13 Feb 2013 08:42:37 +0900 Subject: extcon: max8997: Remove duplicate code related to set H/W line path Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max8997.c | 62 ++++++++++++++++++++++++++++++------- include/linux/mfd/max8997-private.h | 19 +++++++++++- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 0fb1d48b0741..8739b50c2b36 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -94,16 +94,61 @@ static const char *max8997_extcon_cable[] = { NULL, }; +/* + * max8997_muic_set_path - Set hardware line according to attached cable + * @info: the instance including private data of max8997 MUIC + * @value: the path according to attached cable + * @attached: the state of cable (true:attached, false:detached) + * + * The max8997 MUIC device share outside H/W line among a varity of cables, + * so this function set internal path of H/W line according to the type of + * attached cable. + */ +static int max8997_muic_set_path(struct max8997_muic_info *info, + u8 val, bool attached) +{ + int ret = 0; + u8 ctrl1, ctrl2 = 0; + + if (attached) + ctrl1 = val; + else + ctrl1 = CONTROL1_SW_OPEN; + + ret = max8997_update_reg(info->muic, + MAX8997_MUIC_REG_CONTROL1, ctrl1, COMP_SW_MASK); + if (ret < 0) { + dev_err(info->dev, "failed to update MUIC register\n"); + return -EAGAIN; + } + + if (attached) + ctrl2 |= CONTROL2_CPEN_MASK; /* LowPwr=0, CPEn=1 */ + else + ctrl2 |= CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */ + + ret = max8997_update_reg(info->muic, + MAX8997_MUIC_REG_CONTROL2, ctrl2, + CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK); + if (ret < 0) { + dev_err(info->dev, "failed to update MUIC register\n"); + return -EAGAIN; + } + + dev_info(info->dev, + "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n", + ctrl1, ctrl2, attached ? "attached" : "detached"); + + return 0; +} + static int max8997_muic_handle_usb(struct max8997_muic_info *info, enum max8997_muic_usb_type usb_type, bool attached) { int ret = 0; if (usb_type == MAX8997_USB_HOST) { - /* switch to USB */ - ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, - attached ? CONTROL1_SW_USB : CONTROL1_SW_OPEN, - CONTROL1_SW_MASK); + ret = max8997_muic_set_path(info, CONTROL1_SW_USB, attached); if (ret) { dev_err(info->dev, "failed to update muic register\n"); goto out; @@ -131,10 +176,7 @@ static int max8997_muic_handle_dock(struct max8997_muic_info *info, { int ret = 0; - /* switch to AUDIO */ - ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, - attached ? CONTROL1_SW_AUDIO : CONTROL1_SW_OPEN, - CONTROL1_SW_MASK); + ret = max8997_muic_set_path(info, CONTROL1_SW_AUDIO, attached); if (ret) { dev_err(info->dev, "failed to update muic register\n"); goto out; @@ -161,9 +203,7 @@ static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, int ret = 0; /* switch to UART */ - ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, - attached ? CONTROL1_SW_UART : CONTROL1_SW_OPEN, - CONTROL1_SW_MASK); + ret = max8997_muic_set_path(info, CONTROL1_SW_UART, attached); if (ret) { dev_err(info->dev, "failed to update muic register\n"); goto out; diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index acf42e960320..010173a92274 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h @@ -223,7 +223,7 @@ enum max8997_muic_reg { #define COMP2SW_SHIFT 3 #define COMN1SW_MASK (0x7 << COMN1SW_SHIFT) #define COMP2SW_MASK (0x7 << COMP2SW_SHIFT) -#define CONTROL1_SW_MASK (COMP2SW_MASK | COMN1SW_MASK) +#define COMP_SW_MASK (COMP2SW_MASK | COMN1SW_MASK) #define CONTROL1_SW_USB ((1 << COMP2SW_SHIFT) \ | (1 << COMN1SW_SHIFT)) @@ -234,6 +234,23 @@ enum max8997_muic_reg { #define CONTROL1_SW_OPEN ((0 << COMP2SW_SHIFT) \ | (0 << COMN1SW_SHIFT)) +#define CONTROL2_LOWPWR_SHIFT (0) +#define CONTROL2_ADCEN_SHIFT (1) +#define CONTROL2_CPEN_SHIFT (2) +#define CONTROL2_SFOUTASRT_SHIFT (3) +#define CONTROL2_SFOUTORD_SHIFT (4) +#define CONTROL2_ACCDET_SHIFT (5) +#define CONTROL2_USBCPINT_SHIFT (6) +#define CONTROL2_RCPS_SHIFT (7) +#define CONTROL2_LOWPWR_MASK (0x1 << CONTROL2_LOWPWR_SHIFT) +#define CONTROL2_ADCEN_MASK (0x1 << CONTROL2_ADCEN_SHIFT) +#define CONTROL2_CPEN_MASK (0x1 << CONTROL2_CPEN_SHIFT) +#define CONTROL2_SFOUTASRT_MASK (0x1 << CONTROL2_SFOUTASRT_SHIFT) +#define CONTROL2_SFOUTORD_MASK (0x1 << CONTROL2_SFOUTORD_SHIFT) +#define CONTROL2_ACCDET_MASK (0x1 << CONTROL2_ACCDET_SHIFT) +#define CONTROL2_USBCPINT_MASK (0x1 << CONTROL2_USBCPINT_SHIFT) +#define CONTROL2_RCPS_MASK (0x1 << CONTROL2_RCPS_SHIFT) + #define MAX8997_ADC_GROUND 0x00 #define MAX8997_ADC_MHL 0x01 #define MAX8997_ADC_JIG_USB_1 0x18 -- cgit v1.2.3 From 027fcd50500fd87847891d5c2f341c1f002de3e8 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 13 Feb 2013 08:50:00 +0900 Subject: extcon: max8997: Set default of ADC debounce time during initialization This patch set default of ADC Debounce Time(25ms) during probe step. Also, can possible change ADC Debounce Time according to H/W situation by using max8997_set_adc_debounce_time() Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max8997.c | 42 +++++++++++++++++++++++++++++++++++++ include/linux/mfd/max8997-private.h | 7 +++++++ 2 files changed, 49 insertions(+) diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 8739b50c2b36..3206daaf8e08 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -30,6 +30,13 @@ #define DEV_NAME "max8997-muic" +enum max8997_muic_adc_debounce_time { + ADC_DEBOUNCE_TIME_0_5MS = 0, /* 0.5ms */ + ADC_DEBOUNCE_TIME_10MS, /* 10ms */ + ADC_DEBOUNCE_TIME_25MS, /* 25ms */ + ADC_DEBOUNCE_TIME_38_62MS, /* 38.62ms */ +}; + struct max8997_muic_irq { unsigned int irq; const char *name; @@ -94,6 +101,38 @@ static const char *max8997_extcon_cable[] = { NULL, }; +/* + * max8997_muic_set_debounce_time - Set the debounce time of ADC + * @info: the instance including private data of max8997 MUIC + * @time: the debounce time of ADC + */ +static int max8997_muic_set_debounce_time(struct max8997_muic_info *info, + enum max8997_muic_adc_debounce_time time) +{ + int ret; + + switch (time) { + case ADC_DEBOUNCE_TIME_0_5MS: + case ADC_DEBOUNCE_TIME_10MS: + case ADC_DEBOUNCE_TIME_25MS: + case ADC_DEBOUNCE_TIME_38_62MS: + ret = max8997_update_reg(info->muic, + MAX8997_MUIC_REG_CONTROL3, + time << CONTROL3_ADCDBSET_SHIFT, + CONTROL3_ADCDBSET_MASK); + if (ret) { + dev_err(info->dev, "failed to set ADC debounce time\n"); + return -EAGAIN; + } + break; + default: + dev_err(info->dev, "invalid ADC debounce time\n"); + return -EINVAL; + } + + return 0; +}; + /* * max8997_muic_set_path - Set hardware line according to attached cable * @info: the instance including private data of max8997 MUIC @@ -507,6 +546,9 @@ static int max8997_muic_probe(struct platform_device *pdev) } } + /* Set ADC debounce time */ + max8997_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS); + /* Initial device detection */ max8997_muic_detect_dev(info); diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index 010173a92274..cd37a92ccba9 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h @@ -251,6 +251,13 @@ enum max8997_muic_reg { #define CONTROL2_USBCPINT_MASK (0x1 << CONTROL2_USBCPINT_SHIFT) #define CONTROL2_RCPS_MASK (0x1 << CONTROL2_RCPS_SHIFT) +#define CONTROL3_JIGSET_SHIFT (0) +#define CONTROL3_BTLDSET_SHIFT (2) +#define CONTROL3_ADCDBSET_SHIFT (4) +#define CONTROL3_JIGSET_MASK (0x3 << CONTROL3_JIGSET_SHIFT) +#define CONTROL3_BTLDSET_MASK (0x3 << CONTROL3_BTLDSET_SHIFT) +#define CONTROL3_ADCDBSET_MASK (0x3 << CONTROL3_ADCDBSET_SHIFT) + #define MAX8997_ADC_GROUND 0x00 #define MAX8997_ADC_MHL 0x01 #define MAX8997_ADC_JIG_USB_1 0x18 -- cgit v1.2.3 From f73f6232af9131f7b6fc6e377267e4a441727eb3 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 13 Feb 2013 12:05:42 +0900 Subject: extcon: max8997: Consolidate duplicate code for checking ADC/CHG cable type This patch make max8997_muic_get_cable_type() function to remove duplicate code for checking ADC/Charger cable type because almost internal function need to read adc/chg_type value of MUIC register. Also, remove *_detach() function, extcon-max8997 driver treat attach/detach operation of cable in max8997_*_handler() function. Lastly, this patch move defined constant in header file(include/ linux/mfd/max8997.h, max8997-private.h) because defined constant is only used in the 'extcon-max8997.c'. Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max8997.c | 492 +++++++++++++++++++++++------------- include/linux/mfd/max8997-private.h | 9 - include/linux/mfd/max8997.h | 15 -- 3 files changed, 323 insertions(+), 193 deletions(-) diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 3206daaf8e08..35338a090c06 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -44,31 +44,89 @@ struct max8997_muic_irq { }; static struct max8997_muic_irq muic_irqs[] = { - { MAX8997_MUICIRQ_ADCError, "muic-ADC_error" }, - { MAX8997_MUICIRQ_ADCLow, "muic-ADC_low" }, - { MAX8997_MUICIRQ_ADC, "muic-ADC" }, - { MAX8997_MUICIRQ_VBVolt, "muic-VB_voltage" }, - { MAX8997_MUICIRQ_DBChg, "muic-DB_charger" }, - { MAX8997_MUICIRQ_DCDTmr, "muic-DCD_timer" }, - { MAX8997_MUICIRQ_ChgDetRun, "muic-CDR_status" }, - { MAX8997_MUICIRQ_ChgTyp, "muic-charger_type" }, - { MAX8997_MUICIRQ_OVP, "muic-over_voltage" }, + { MAX8997_MUICIRQ_ADCError, "muic-ADCERROR" }, + { MAX8997_MUICIRQ_ADCLow, "muic-ADCLOW" }, + { MAX8997_MUICIRQ_ADC, "muic-ADC" }, + { MAX8997_MUICIRQ_VBVolt, "muic-VBVOLT" }, + { MAX8997_MUICIRQ_DBChg, "muic-DBCHG" }, + { MAX8997_MUICIRQ_DCDTmr, "muic-DCDTMR" }, + { MAX8997_MUICIRQ_ChgDetRun, "muic-CHGDETRUN" }, + { MAX8997_MUICIRQ_ChgTyp, "muic-CHGTYP" }, + { MAX8997_MUICIRQ_OVP, "muic-OVP" }, +}; + +/* Define supported cable type */ +enum max8997_muic_acc_type { + MAX8997_MUIC_ADC_GROUND = 0x0, + MAX8997_MUIC_ADC_MHL, /* MHL*/ + MAX8997_MUIC_ADC_REMOTE_S1_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S2_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S3_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S4_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S5_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S6_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S7_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S8_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S9_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S10_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S11_BUTTON, + MAX8997_MUIC_ADC_REMOTE_S12_BUTTON, + MAX8997_MUIC_ADC_RESERVED_ACC_1, + MAX8997_MUIC_ADC_RESERVED_ACC_2, + MAX8997_MUIC_ADC_RESERVED_ACC_3, + MAX8997_MUIC_ADC_RESERVED_ACC_4, + MAX8997_MUIC_ADC_RESERVED_ACC_5, + MAX8997_MUIC_ADC_CEA936_AUDIO, + MAX8997_MUIC_ADC_PHONE_POWERED_DEV, + MAX8997_MUIC_ADC_TTY_CONVERTER, + MAX8997_MUIC_ADC_UART_CABLE, + MAX8997_MUIC_ADC_CEA936A_TYPE1_CHG, + MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF, /* JIG-USB-OFF */ + MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON, /* JIG-USB-ON */ + MAX8997_MUIC_ADC_AV_CABLE_NOLOAD, /* DESKDOCK */ + MAX8997_MUIC_ADC_CEA936A_TYPE2_CHG, + MAX8997_MUIC_ADC_FACTORY_MODE_UART_OFF, /* JIG-UART */ + MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON, /* CARDOCK */ + MAX8997_MUIC_ADC_AUDIO_MODE_REMOTE, + MAX8997_MUIC_ADC_OPEN, /* OPEN */ +}; + +enum max8997_muic_cable_group { + MAX8997_CABLE_GROUP_ADC = 0, + MAX8997_CABLE_GROUP_ADC_GND, + MAX8997_CABLE_GROUP_CHG, + MAX8997_CABLE_GROUP_VBVOLT, +}; + +enum max8997_muic_usb_type { + MAX8997_USB_HOST, + MAX8997_USB_DEVICE, +}; + +enum max8997_muic_charger_type { + MAX8997_CHARGER_TYPE_NONE = 0, + MAX8997_CHARGER_TYPE_USB, + MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT, + MAX8997_CHARGER_TYPE_DEDICATED_CHG, + MAX8997_CHARGER_TYPE_500MA, + MAX8997_CHARGER_TYPE_1A, + MAX8997_CHARGER_TYPE_DEAD_BATTERY = 7, }; struct max8997_muic_info { struct device *dev; struct i2c_client *muic; - struct max8997_muic_platform_data *muic_pdata; + struct extcon_dev *edev; + int prev_cable_type; + int prev_chg_type; + u8 status[2]; int irq; struct work_struct irq_work; - - enum max8997_muic_charger_type pre_charger_type; - int pre_adc; - struct mutex mutex; - struct extcon_dev *edev; + struct max8997_muic_platform_data *muic_pdata; + enum max8997_muic_charger_type pre_charger_type; }; enum { @@ -181,6 +239,83 @@ static int max8997_muic_set_path(struct max8997_muic_info *info, return 0; } +/* + * max8997_muic_get_cable_type - Return cable type and check cable state + * @info: the instance including private data of max8997 MUIC + * @group: the path according to attached cable + * @attached: store cable state and return + * + * This function check the cable state either attached or detached, + * and then divide precise type of cable according to cable group. + * - MAX8997_CABLE_GROUP_ADC + * - MAX8997_CABLE_GROUP_CHG + */ +static int max8997_muic_get_cable_type(struct max8997_muic_info *info, + enum max8997_muic_cable_group group, bool *attached) +{ + int cable_type = 0; + int adc; + int chg_type; + + switch (group) { + case MAX8997_CABLE_GROUP_ADC: + /* + * Read ADC value to check cable type and decide cable state + * according to cable type + */ + adc = info->status[0] & STATUS1_ADC_MASK; + adc >>= STATUS1_ADC_SHIFT; + + /* + * Check current cable state/cable type and store cable type + * (info->prev_cable_type) for handling cable when cable is + * detached. + */ + if (adc == MAX8997_MUIC_ADC_OPEN) { + *attached = false; + + cable_type = info->prev_cable_type; + info->prev_cable_type = MAX8997_MUIC_ADC_OPEN; + } else { + *attached = true; + + cable_type = info->prev_cable_type = adc; + } + break; + case MAX8997_CABLE_GROUP_CHG: + /* + * Read charger type to check cable type and decide cable state + * according to type of charger cable. + */ + chg_type = info->status[1] & STATUS2_CHGTYP_MASK; + chg_type >>= STATUS2_CHGTYP_SHIFT; + + if (chg_type == MAX8997_CHARGER_TYPE_NONE) { + *attached = false; + + cable_type = info->prev_chg_type; + info->prev_chg_type = MAX8997_CHARGER_TYPE_NONE; + } else { + *attached = true; + + /* + * Check current cable state/cable type and store cable + * type(info->prev_chg_type) for handling cable when + * charger cable is detached. + */ + cable_type = info->prev_chg_type = chg_type; + } + + break; + default: + dev_err(info->dev, "Unknown cable group (%d)\n", group); + cable_type = -EINVAL; + break; + } + + return cable_type; +} + static int max8997_muic_handle_usb(struct max8997_muic_info *info, enum max8997_muic_usb_type usb_type, bool attached) { @@ -188,9 +323,9 @@ static int max8997_muic_handle_usb(struct max8997_muic_info *info, if (usb_type == MAX8997_USB_HOST) { ret = max8997_muic_set_path(info, CONTROL1_SW_USB, attached); - if (ret) { + if (ret < 0) { dev_err(info->dev, "failed to update muic register\n"); - goto out; + return ret; } } @@ -202,38 +337,39 @@ static int max8997_muic_handle_usb(struct max8997_muic_info *info, extcon_set_cable_state(info->edev, "USB", attached); break; default: - ret = -EINVAL; - break; + dev_err(info->dev, "failed to detect %s usb cable\n", + attached ? "attached" : "detached"); + return -EINVAL; } -out: - return ret; + return 0; } static int max8997_muic_handle_dock(struct max8997_muic_info *info, - int adc, bool attached) + int cable_type, bool attached) { int ret = 0; ret = max8997_muic_set_path(info, CONTROL1_SW_AUDIO, attached); if (ret) { dev_err(info->dev, "failed to update muic register\n"); - goto out; + return ret; } - switch (adc) { - case MAX8997_ADC_DESKDOCK: + switch (cable_type) { + case MAX8997_MUIC_ADC_AV_CABLE_NOLOAD: extcon_set_cable_state(info->edev, "Dock-desk", attached); break; - case MAX8997_ADC_CARDOCK: + case MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON: extcon_set_cable_state(info->edev, "Dock-card", attached); break; default: - ret = -EINVAL; - break; + dev_err(info->dev, "failed to detect %s dock device\n", + attached ? "attached" : "detached"); + return -EINVAL; } -out: - return ret; + + return 0; } static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, @@ -245,193 +381,185 @@ static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, ret = max8997_muic_set_path(info, CONTROL1_SW_UART, attached); if (ret) { dev_err(info->dev, "failed to update muic register\n"); - goto out; + return -EINVAL; } extcon_set_cable_state(info->edev, "JIG", attached); -out: - return ret; -} -static int max8997_muic_handle_adc_detach(struct max8997_muic_info *info) -{ - int ret = 0; - - switch (info->pre_adc) { - case MAX8997_ADC_GROUND: - ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, false); - break; - case MAX8997_ADC_MHL: - extcon_set_cable_state(info->edev, "MHL", false); - break; - case MAX8997_ADC_JIG_USB_1: - case MAX8997_ADC_JIG_USB_2: - ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, false); - break; - case MAX8997_ADC_DESKDOCK: - case MAX8997_ADC_CARDOCK: - ret = max8997_muic_handle_dock(info, info->pre_adc, false); - break; - case MAX8997_ADC_JIG_UART: - ret = max8997_muic_handle_jig_uart(info, false); - break; - default: - break; - } - - return ret; + return 0; } -static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc) +static int max8997_muic_adc_handler(struct max8997_muic_info *info) { + int cable_type; + bool attached; int ret = 0; - switch (adc) { - case MAX8997_ADC_GROUND: - ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, true); - break; - case MAX8997_ADC_MHL: - extcon_set_cable_state(info->edev, "MHL", true); - break; - case MAX8997_ADC_JIG_USB_1: - case MAX8997_ADC_JIG_USB_2: - ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, true); - break; - case MAX8997_ADC_DESKDOCK: - case MAX8997_ADC_CARDOCK: - ret = max8997_muic_handle_dock(info, adc, true); - break; - case MAX8997_ADC_JIG_UART: - ret = max8997_muic_handle_jig_uart(info, true); - break; - case MAX8997_ADC_OPEN: - ret = max8997_muic_handle_adc_detach(info); - break; - default: - ret = -EINVAL; - goto out; - } - - info->pre_adc = adc; -out: - return ret; -} - -static int max8997_muic_handle_charger_type_detach( - struct max8997_muic_info *info) -{ - switch (info->pre_charger_type) { - case MAX8997_CHARGER_TYPE_USB: - extcon_set_cable_state(info->edev, "USB", false); - break; - case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: - extcon_set_cable_state(info->edev, "Charge-downstream", false); - break; - case MAX8997_CHARGER_TYPE_DEDICATED_CHG: - extcon_set_cable_state(info->edev, "TA", false); - break; - case MAX8997_CHARGER_TYPE_500MA: - extcon_set_cable_state(info->edev, "Slow-charger", false); - break; - case MAX8997_CHARGER_TYPE_1A: - extcon_set_cable_state(info->edev, "Fast-charger", false); - break; + /* Check cable state which is either detached or attached */ + cable_type = max8997_muic_get_cable_type(info, + MAX8997_CABLE_GROUP_ADC, &attached); + + switch (cable_type) { + case MAX8997_MUIC_ADC_GROUND: + ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, attached); + if (ret < 0) + return ret; + break; + case MAX8997_MUIC_ADC_MHL: + extcon_set_cable_state(info->edev, "MHL", attached); + break; + case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF: + case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON: + ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, attached); + if (ret < 0) + return ret; + break; + case MAX8997_MUIC_ADC_AV_CABLE_NOLOAD: + case MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON: + ret = max8997_muic_handle_dock(info, cable_type, attached); + if (ret < 0) + return ret; + break; + case MAX8997_MUIC_ADC_FACTORY_MODE_UART_OFF: + ret = max8997_muic_handle_jig_uart(info, attached); + break; + case MAX8997_MUIC_ADC_REMOTE_S1_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S2_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S3_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S4_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S5_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S6_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S7_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S8_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S9_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S10_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S11_BUTTON: + case MAX8997_MUIC_ADC_REMOTE_S12_BUTTON: + case MAX8997_MUIC_ADC_RESERVED_ACC_1: + case MAX8997_MUIC_ADC_RESERVED_ACC_2: + case MAX8997_MUIC_ADC_RESERVED_ACC_3: + case MAX8997_MUIC_ADC_RESERVED_ACC_4: + case MAX8997_MUIC_ADC_RESERVED_ACC_5: + case MAX8997_MUIC_ADC_CEA936_AUDIO: + case MAX8997_MUIC_ADC_PHONE_POWERED_DEV: + case MAX8997_MUIC_ADC_TTY_CONVERTER: + case MAX8997_MUIC_ADC_UART_CABLE: + case MAX8997_MUIC_ADC_CEA936A_TYPE1_CHG: + case MAX8997_MUIC_ADC_CEA936A_TYPE2_CHG: + case MAX8997_MUIC_ADC_AUDIO_MODE_REMOTE: + /* + * This cable isn't used in general case if it is specially + * needed to detect additional cable, should implement + * proper operation when this cable is attached/detached. + */ + dev_info(info->dev, + "cable is %s but it isn't used (type:0x%x)\n", + attached ? "attached" : "detached", cable_type); + return -EAGAIN; default: + dev_err(info->dev, + "failed to detect %s unknown cable (type:0x%x)\n", + attached ? "attached" : "detached", cable_type); return -EINVAL; } return 0; } -static int max8997_muic_handle_charger_type(struct max8997_muic_info *info, - enum max8997_muic_charger_type charger_type) +static int max8997_muic_chg_handler(struct max8997_muic_info *info) { - u8 adc; - int ret; + int chg_type; + bool attached; + int adc; - ret = max8997_read_reg(info->muic, MAX8997_MUIC_REG_STATUS1, &adc); - if (ret) { - dev_err(info->dev, "failed to read muic register\n"); - goto out; - } + chg_type = max8997_muic_get_cable_type(info, + MAX8997_CABLE_GROUP_CHG, &attached); - switch (charger_type) { + switch (chg_type) { case MAX8997_CHARGER_TYPE_NONE: - ret = max8997_muic_handle_charger_type_detach(info); break; case MAX8997_CHARGER_TYPE_USB: - if ((adc & STATUS1_ADC_MASK) == MAX8997_ADC_OPEN) { + adc = info->status[0] & STATUS1_ADC_MASK; + adc >>= STATUS1_ADC_SHIFT; + + if ((adc & STATUS1_ADC_MASK) == MAX8997_MUIC_ADC_OPEN) { max8997_muic_handle_usb(info, - MAX8997_USB_DEVICE, true); + MAX8997_USB_DEVICE, attached); } break; case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: - extcon_set_cable_state(info->edev, "Charge-downstream", true); + extcon_set_cable_state(info->edev, "Charge-downstream", attached); break; case MAX8997_CHARGER_TYPE_DEDICATED_CHG: - extcon_set_cable_state(info->edev, "TA", true); + extcon_set_cable_state(info->edev, "TA", attached); break; case MAX8997_CHARGER_TYPE_500MA: - extcon_set_cable_state(info->edev, "Slow-charger", true); + extcon_set_cable_state(info->edev, "Slow-charger", attached); break; case MAX8997_CHARGER_TYPE_1A: - extcon_set_cable_state(info->edev, "Fast-charger", true); + extcon_set_cable_state(info->edev, "Fast-charger", attached); break; default: - ret = -EINVAL; - goto out; + dev_err(info->dev, + "failed to detect %s unknown chg cable (type:0x%x)\n", + attached ? "attached" : "detached", chg_type); + return -EINVAL; } - info->pre_charger_type = charger_type; -out: - return ret; + return 0; } static void max8997_muic_irq_work(struct work_struct *work) { struct max8997_muic_info *info = container_of(work, struct max8997_muic_info, irq_work); - u8 status[2]; - u8 adc, chg_type; int irq_type = 0; int i, ret; + if (!info->edev) + return; + mutex_lock(&info->mutex); + for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++) + if (info->irq == muic_irqs[i].virq) + irq_type = muic_irqs[i].irq; + ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, - 2, status); + 2, info->status); if (ret) { dev_err(info->dev, "failed to read muic register\n"); mutex_unlock(&info->mutex); return; } - dev_dbg(info->dev, "%s: STATUS1:0x%x, 2:0x%x\n", __func__, - status[0], status[1]); - - for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++) - if (info->irq == muic_irqs[i].virq) - irq_type = muic_irqs[i].irq; - switch (irq_type) { + case MAX8997_MUICIRQ_ADCError: + case MAX8997_MUICIRQ_ADCLow: case MAX8997_MUICIRQ_ADC: - adc = status[0] & STATUS1_ADC_MASK; - adc >>= STATUS1_ADC_SHIFT; - - max8997_muic_handle_adc(info, adc); + /* Handle all of cable except for charger cable */ + ret = max8997_muic_adc_handler(info); break; + case MAX8997_MUICIRQ_VBVolt: + case MAX8997_MUICIRQ_DBChg: + case MAX8997_MUICIRQ_DCDTmr: + case MAX8997_MUICIRQ_ChgDetRun: case MAX8997_MUICIRQ_ChgTyp: - chg_type = status[1] & STATUS2_CHGTYP_MASK; - chg_type >>= STATUS2_CHGTYP_SHIFT; - - max8997_muic_handle_charger_type(info, chg_type); + /* Handle charger cable */ + ret = max8997_muic_chg_handler(info); + break; + case MAX8997_MUICIRQ_OVP: break; default: dev_info(info->dev, "misc interrupt: irq %d occurred\n", irq_type); - break; + mutex_unlock(&info->mutex); + return; } + if (ret < 0) + dev_err(info->dev, "failed to handle MUIC interrupt\n"); + mutex_unlock(&info->mutex); return; @@ -449,29 +577,49 @@ static irqreturn_t max8997_muic_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static void max8997_muic_detect_dev(struct max8997_muic_info *info) +static int max8997_muic_detect_dev(struct max8997_muic_info *info) { - int ret; - u8 status[2], adc, chg_type; + int ret = 0; + int adc; + int chg_type; + bool attached; - ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, - 2, status); + mutex_lock(&info->mutex); + + /* Read STATUSx register to detect accessory */ + ret = max8997_bulk_read(info->muic, + MAX8997_MUIC_REG_STATUS1, 2, info->status); if (ret) { - dev_err(info->dev, "failed to read muic register\n"); - return; + dev_err(info->dev, "failed to read MUIC register\n"); + mutex_unlock(&info->mutex); + return -EINVAL; } - dev_info(info->dev, "STATUS1:0x%x, STATUS2:0x%x\n", - status[0], status[1]); + adc = max8997_muic_get_cable_type(info, MAX8997_CABLE_GROUP_ADC, + &attached); + if (attached && adc != MAX8997_MUIC_ADC_OPEN) { + ret = max8997_muic_adc_handler(info); + if (ret < 0) { + dev_err(info->dev, "Cannot detect ADC cable\n"); + mutex_unlock(&info->mutex); + return ret; + } + } - adc = status[0] & STATUS1_ADC_MASK; - adc >>= STATUS1_ADC_SHIFT; + chg_type = max8997_muic_get_cable_type(info, MAX8997_CABLE_GROUP_CHG, + &attached); + if (attached && chg_type != MAX8997_CHARGER_TYPE_NONE) { + ret = max8997_muic_chg_handler(info); + if (ret < 0) { + dev_err(info->dev, "Cannot detect charger cable\n"); + mutex_unlock(&info->mutex); + return ret; + } + } - chg_type = status[1] & STATUS2_CHGTYP_MASK; - chg_type >>= STATUS2_CHGTYP_SHIFT; + mutex_unlock(&info->mutex); - max8997_muic_handle_adc(info, adc); - max8997_muic_handle_charger_type(info, chg_type); + return 0; } static int max8997_muic_probe(struct platform_device *pdev) @@ -550,10 +698,16 @@ static int max8997_muic_probe(struct platform_device *pdev) max8997_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS); /* Initial device detection */ - max8997_muic_detect_dev(info); + ret = max8997_muic_detect_dev(info); + if (ret < 0) { + dev_err(&pdev->dev, "failed to detect cable type\n"); + goto err_extcon; + } return ret; +err_extcon: + extcon_dev_unregister(info->edev); err_irq: while (--i >= 0) free_irq(muic_irqs[i].virq, info); diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index cd37a92ccba9..fb465dfbb59e 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h @@ -258,15 +258,6 @@ enum max8997_muic_reg { #define CONTROL3_BTLDSET_MASK (0x3 << CONTROL3_BTLDSET_SHIFT) #define CONTROL3_ADCDBSET_MASK (0x3 << CONTROL3_ADCDBSET_SHIFT) -#define MAX8997_ADC_GROUND 0x00 -#define MAX8997_ADC_MHL 0x01 -#define MAX8997_ADC_JIG_USB_1 0x18 -#define MAX8997_ADC_JIG_USB_2 0x19 -#define MAX8997_ADC_DESKDOCK 0x1a -#define MAX8997_ADC_JIG_UART 0x1c -#define MAX8997_ADC_CARDOCK 0x1d -#define MAX8997_ADC_OPEN 0x1f - enum max8997_haptic_reg { MAX8997_HAPTIC_REG_GENERAL = 0x00, MAX8997_HAPTIC_REG_CONF1 = 0x01, diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h index 1d4a4fe6ac33..65f8d6a3a608 100644 --- a/include/linux/mfd/max8997.h +++ b/include/linux/mfd/max8997.h @@ -78,21 +78,6 @@ struct max8997_regulator_data { struct device_node *reg_node; }; -enum max8997_muic_usb_type { - MAX8997_USB_HOST, - MAX8997_USB_DEVICE, -}; - -enum max8997_muic_charger_type { - MAX8997_CHARGER_TYPE_NONE = 0, - MAX8997_CHARGER_TYPE_USB, - MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT, - MAX8997_CHARGER_TYPE_DEDICATED_CHG, - MAX8997_CHARGER_TYPE_500MA, - MAX8997_CHARGER_TYPE_1A, - MAX8997_CHARGER_TYPE_DEAD_BATTERY = 7, -}; - struct max8997_muic_reg_data { u8 addr; u8 data; -- cgit v1.2.3 From 685dc9a7dbfede28cc4a0fe4e65804194ec04fa5 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 13 Feb 2013 15:04:15 +0900 Subject: extcon: max8997: Set default UART/USB path on probe This patch set default H/W line path according to platfomr data. The MAX8997 MUIC device can possibly set UART/USB or UART_AUX /USB_AUX to internal H/W line path of MUIC device. Namely, only one H/W line is used for two operation. For example, if H/W line path of MAX8997 device set UART/USB, micro usb cable is connected to AP(Application Processor) and if H/W line path set UART_AUX/USB_AUX, micro usb cable is connected to CP(Coprocessor). Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max8997.c | 28 ++++++++++++++++++++++++++-- include/linux/mfd/max8997.h | 7 +++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 35338a090c06..349f65f6a4a4 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -127,6 +127,13 @@ struct max8997_muic_info { struct max8997_muic_platform_data *muic_pdata; enum max8997_muic_charger_type pre_charger_type; + + /* + * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB + * h/w path of COMP2/COMN1 on CONTROL1 register. + */ + int path_usb; + int path_uart; }; enum { @@ -322,7 +329,7 @@ static int max8997_muic_handle_usb(struct max8997_muic_info *info, int ret = 0; if (usb_type == MAX8997_USB_HOST) { - ret = max8997_muic_set_path(info, CONTROL1_SW_USB, attached); + ret = max8997_muic_set_path(info, info->path_usb, attached); if (ret < 0) { dev_err(info->dev, "failed to update muic register\n"); return ret; @@ -378,7 +385,7 @@ static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, int ret = 0; /* switch to UART */ - ret = max8997_muic_set_path(info, CONTROL1_SW_UART, attached); + ret = max8997_muic_set_path(info, info->path_uart, attached); if (ret) { dev_err(info->dev, "failed to update muic register\n"); return -EINVAL; @@ -694,6 +701,23 @@ static int max8997_muic_probe(struct platform_device *pdev) } } + /* + * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB + * h/w path of COMP2/COMN1 on CONTROL1 register. + */ + if (pdata->muic_pdata->path_uart) + info->path_uart = pdata->muic_pdata->path_uart; + else + info->path_uart = CONTROL1_SW_UART; + + if (pdata->muic_pdata->path_usb) + info->path_usb = pdata->muic_pdata->path_usb; + else + info->path_usb = CONTROL1_SW_USB; + + /* Set initial path for UART */ + max8997_muic_set_path(info, info->path_uart, true); + /* Set ADC debounce time */ max8997_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS); diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h index 65f8d6a3a608..2d2d67b6a393 100644 --- a/include/linux/mfd/max8997.h +++ b/include/linux/mfd/max8997.h @@ -92,6 +92,13 @@ struct max8997_muic_reg_data { struct max8997_muic_platform_data { struct max8997_muic_reg_data *init_data; int num_init_data; + + /* + * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB + * h/w path of COMP2/COMN1 on CONTROL1 register. + */ + int path_usb; + int path_uart; }; enum max8997_haptic_motor_type { -- cgit v1.2.3 From af5eb1a13273447c5708cd5425696f3b6f79dd9b Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 13 Feb 2013 15:10:00 +0900 Subject: extcon: max8997: Use workqueue to check cable state after completing boot of platform This patch use delayed workqueue to check cable state after a certain time. If extcon-max8997 driver check cable state during booting of platform, this couldn't send the correct notification of cable state to extcon consumer. Alwasys, this driver should check cable state after the completion of platform initialization Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max8997.c | 45 ++++++++++++++++++++++++++++++++--------- include/linux/mfd/max8997.h | 3 +++ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 349f65f6a4a4..e636d950ad6c 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -29,6 +29,7 @@ #include #define DEV_NAME "max8997-muic" +#define DELAY_MS_DEFAULT 20000 /* unit: millisecond */ enum max8997_muic_adc_debounce_time { ADC_DEBOUNCE_TIME_0_5MS = 0, /* 0.5ms */ @@ -128,6 +129,14 @@ struct max8997_muic_info { struct max8997_muic_platform_data *muic_pdata; enum max8997_muic_charger_type pre_charger_type; + /* + * Use delayed workqueue to detect cable state and then + * notify cable state to notifiee/platform through uevent. + * After completing the booting of platform, the extcon provider + * driver should notify cable state to upper layer. + */ + struct delayed_work wq_detcable; + /* * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB * h/w path of COMP2/COMN1 on CONTROL1 register. @@ -629,11 +638,23 @@ static int max8997_muic_detect_dev(struct max8997_muic_info *info) return 0; } +static void max8997_muic_detect_cable_wq(struct work_struct *work) +{ + struct max8997_muic_info *info = container_of(to_delayed_work(work), + struct max8997_muic_info, wq_detcable); + int ret; + + ret = max8997_muic_detect_dev(info); + if (ret < 0) + pr_err("failed to detect cable type\n"); +} + static int max8997_muic_probe(struct platform_device *pdev) { struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent); struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev); struct max8997_muic_info *info; + int delay_jiffies; int ret, i; info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info), @@ -721,17 +742,23 @@ static int max8997_muic_probe(struct platform_device *pdev) /* Set ADC debounce time */ max8997_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS); - /* Initial device detection */ - ret = max8997_muic_detect_dev(info); - if (ret < 0) { - dev_err(&pdev->dev, "failed to detect cable type\n"); - goto err_extcon; - } + /* + * Detect accessory after completing the initialization of platform + * + * - Use delayed workqueue to detect cable state and then + * notify cable state to notifiee/platform through uevent. + * After completing the booting of platform, the extcon provider + * driver should notify cable state to upper layer. + */ + INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq); + if (pdata->muic_pdata->detcable_delay_ms) + delay_jiffies = msecs_to_jiffies(pdata->muic_pdata->detcable_delay_ms); + else + delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); + schedule_delayed_work(&info->wq_detcable, delay_jiffies); - return ret; + return 0; -err_extcon: - extcon_dev_unregister(info->edev); err_irq: while (--i >= 0) free_irq(muic_irqs[i].virq, info); diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h index 2d2d67b6a393..cf815577bd68 100644 --- a/include/linux/mfd/max8997.h +++ b/include/linux/mfd/max8997.h @@ -93,6 +93,9 @@ struct max8997_muic_platform_data { struct max8997_muic_reg_data *init_data; int num_init_data; + /* Check cable state after certain delay */ + int detcable_delay_ms; + /* * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB * h/w path of COMP2/COMN1 on CONTROL1 register. -- cgit v1.2.3