Commit 74a8e349 authored by Hakan Berg's avatar Hakan Berg Committed by Anton Vorontsov
Browse files

ab8500_bm: Adds support for Car/Travel Adapters



The Travel and Carkit adapter should be handled directly by
the charger driver.

Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
Signed-off-by: default avatarMarcus Cooper <marcus.xm.cooper@stericsson.com>
Reviewed-by: default avatarJonas ABERG <jonas.aberg@stericsson.com>
Signed-off-by: default avatarAnton Vorontsov <anton@enomsg.org>
parent d36e3e6d
Loading
Loading
Loading
Loading
+68 −24
Original line number Diff line number Diff line
@@ -108,6 +108,18 @@ enum ab8500_charger_link_status {
	USB_STAT_HM_IDGND,
	USB_STAT_RESERVED,
	USB_STAT_NOT_VALID_LINK,
	USB_STAT_PHY_EN,
	USB_STAT_SUP_NO_IDGND_VBUS,
	USB_STAT_SUP_IDGND_VBUS,
	USB_STAT_CHARGER_LINE_1,
	USB_STAT_CARKIT_1,
	USB_STAT_CARKIT_2,
	USB_STAT_ACA_DOCK_CHARGER,
	USB_STAT_SAMSUNG_USB_PHY_DIS,
	USB_STAT_SAMSUNG_USB_PHY_ENA,
	USB_STAT_SAMSUNG_UART_PHY_DIS,
	USB_STAT_SAMSUNG_UART_PHY_ENA,
	USB_STAT_MOTOROLA_USB_PHY_ENA,
};

enum ab8500_usb_state {
@@ -600,10 +612,14 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di,
		break;
	case USB_STAT_HOST_CHG_HS_CHIRP:
		di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5;
		dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status,
				di->max_usb_in_curr);
		break;
	case USB_STAT_HOST_CHG_HS:
	case USB_STAT_ACA_RID_C_HS:
		di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P9;
		dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status,
				di->max_usb_in_curr);
		break;
	case USB_STAT_ACA_RID_A:
		/*
@@ -611,6 +627,8 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di,
		 * can consume (300mA). Closest level is 1100mA
		 */
		di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P1;
		dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status,
				di->max_usb_in_curr);
		break;
	case USB_STAT_ACA_RID_B:
		/*
@@ -618,34 +636,50 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di,
		 * 100mA for potential accessory). Closest level is 1300mA
		 */
		di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P3;
		dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status,
				di->max_usb_in_curr);
		break;
	case USB_STAT_DEDICATED_CHG:
	case USB_STAT_HOST_CHG_NM:
	case USB_STAT_ACA_RID_C_HS_CHIRP:
	case USB_STAT_DEDICATED_CHG:
	case USB_STAT_ACA_RID_C_NM:
	case USB_STAT_ACA_RID_C_HS_CHIRP:
		di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5;
		dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status,
				di->max_usb_in_curr);
		break;
	case USB_STAT_HM_IDGND:
	case USB_STAT_NOT_VALID_LINK:
	case USB_STAT_NOT_CONFIGURED:
		dev_err(di->dev, "USB Type - Charging not allowed\n");
		di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05;
		ret = -ENXIO;
		break;
	case USB_STAT_RESERVED:
		/*
		 * This state is used to indicate that VBUS has dropped below
		 * the detection level 4 times in a row. This is due to the
		 * charger output current is set to high making the charger
		 * voltage collapse. This have to be propagated through to
		 * chargalg. This is done using the property
		 * POWER_SUPPLY_PROP_CURRENT_AVG = 1
		 */
		if (is_ab8500(di->parent)) {
			di->flags.vbus_collapse = true;
		dev_dbg(di->dev, "USB Type - USB_STAT_RESERVED "
			dev_err(di->dev, "USB Type - USB_STAT_RESERVED "
						"VBUS has collapsed\n");
		ret = -1;
			ret = -ENXIO;
			break;
	case USB_STAT_HM_IDGND:
	case USB_STAT_NOT_CONFIGURED:
	case USB_STAT_NOT_VALID_LINK:
		dev_err(di->dev, "USB Type - Charging not allowed\n");
		}
		if (is_ab9540(di->parent) || is_ab8505(di->parent)) {
			dev_dbg(di->dev, "USB Type - Charging not allowed\n");
			di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05;
			dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d",
					link_status, di->max_usb_in_curr);
			ret = -ENXIO;
			break;
		}
		break;
	case USB_STAT_CARKIT_1:
	case USB_STAT_CARKIT_2:
	case USB_STAT_ACA_DOCK_CHARGER:
	case USB_STAT_CHARGER_LINE_1:
		di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5;
		dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status,
				di->max_usb_in_curr);
		break;

	default:
		dev_err(di->dev, "USB Type - Unknown\n");
		di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05;
@@ -677,8 +711,14 @@ static int ab8500_charger_read_usb_type(struct ab8500_charger *di)
		dev_err(di->dev, "%s ab8500 read failed\n", __func__);
		return ret;
	}
	if (is_ab8500(di->parent)) {
		ret = abx500_get_register_interruptible(di->dev, AB8500_USB,
				AB8500_USB_LINE_STAT_REG, &val);
	} else {
		if (is_ab9540(di->parent) || is_ab8505(di->parent))
			ret = abx500_get_register_interruptible(di->dev,
				AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val);
	}
	if (ret < 0) {
		dev_err(di->dev, "%s ab8500 read failed\n", __func__);
		return ret;
@@ -718,8 +758,13 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di)
			dev_err(di->dev, "%s ab8500 read failed\n", __func__);
			return ret;
		}
		ret = abx500_get_register_interruptible(di->dev, AB8500_USB,
			AB8500_USB_LINE_STAT_REG, &val);

		if (is_ab8500(di->parent))
			ret = abx500_get_register_interruptible(di->dev,
				AB8500_USB, AB8500_USB_LINE_STAT_REG, &val);
		else
			ret = abx500_get_register_interruptible(di->dev,
				AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val);
		if (ret < 0) {
			dev_err(di->dev, "%s ab8500 read failed\n", __func__);
			return ret;
@@ -2944,7 +2989,6 @@ static int ab8500_charger_probe(struct platform_device *pdev)
	}

	if (charger_status & USB_PW_CONN) {
		dev_dbg(di->dev, "VBUS Detect during startup\n");
		di->vbus_detected = true;
		di->vbus_detected_start = true;
		queue_work(di->charger_wq,
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
 * Bank : 0x5
 */
#define AB8500_USB_LINE_STAT_REG	0x80
#define AB8500_USB_LINK1_STAT_REG	0x94

/*
 * Charger / status register offfsets