diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 547f6ea1b695679abc9979804f0e84339c9735ff..b5c7a3975024f3afd3197e0955d04a80b4488ef7 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -80,6 +80,7 @@ /* UsbLineStatus register bit masks */ #define AB8500_USB_LINK_STATUS 0x78 +#define AB8505_USB_LINK_STATUS 0xF8 #define AB8500_STD_HOST_SUSP 0x18 /* Watchdog timeout constant */ @@ -809,10 +810,12 @@ static int ab8500_charger_read_usb_type(struct ab8500_charger *di) 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)) + } 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); + } else { + dev_err(di->dev, "%s unsupported analog baseband\n", __func__); + return -ENXIO; } if (ret < 0) { dev_err(di->dev, "%s ab8500 read failed\n", __func__); @@ -820,7 +823,14 @@ static int ab8500_charger_read_usb_type(struct ab8500_charger *di) } /* get the USB type */ - val = (val & AB8500_USB_LINK_STATUS) >> 3; + if (is_ab8500(di->parent)) { + val = (val & AB8500_USB_LINK_STATUS) >> 3; + } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { + val = (val & AB8505_USB_LINK_STATUS) >> 3; + } else { + dev_err(di->dev, "%s unsupported analog baseband\n", __func__); + return -ENXIO; + } ret = ab8500_charger_max_usb_curr(di, (enum ab8500_charger_link_status) val); @@ -856,12 +866,16 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) return ret; } - if (is_ab8500(di->parent)) + if (is_ab8500(di->parent)) { ret = abx500_get_register_interruptible(di->dev, AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); - else + } 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); + } else { + dev_err(di->dev, "%s unsupported analog baseband\n", __func__); + return -ENXIO; + } if (ret < 0) { dev_err(di->dev, "%s ab8500 read failed\n", __func__); return ret; @@ -875,7 +889,14 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) */ /* get the USB type */ - val = (val & AB8500_USB_LINK_STATUS) >> 3; + if (is_ab8500(di->parent)) { + val = (val & AB8500_USB_LINK_STATUS) >> 3; + } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { + val = (val & AB8505_USB_LINK_STATUS) >> 3; + } else { + dev_err(di->dev, "%s unsupported analog baseband\n", __func__); + return -ENXIO; + } if (val) break; } @@ -2287,6 +2308,7 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) int detected_chargers; int ret; u8 val; + u8 link_status; struct ab8500_charger *di = container_of(work, struct ab8500_charger, usb_link_status_work); @@ -2313,8 +2335,13 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) else dev_dbg(di->dev, "Error reading USB link status\n"); + if (is_ab9540(di->parent) || is_ab8505(di->parent)) + link_status = AB8505_USB_LINK_STATUS; + else + link_status = AB8500_USB_LINK_STATUS; + if (detected_chargers & USB_PW_CONN) { - if (((val & AB8500_USB_LINK_STATUS) >> 3) == USB_STAT_NOT_VALID_LINK && + if (((val & link_status) >> 3) == USB_STAT_NOT_VALID_LINK && di->invalid_charger_detect_state == 0) { dev_dbg(di->dev, "Invalid charger detected, state= 0\n"); /*Enable charger*/ @@ -2337,7 +2364,7 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) ret = abx500_get_register_interruptible(di->dev, AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); dev_dbg(di->dev, "USB link status= 0x%02x\n", - (val & AB8500_USB_LINK_STATUS) >> 3); + (val & link_status) >> 3); di->invalid_charger_detect_state = 2; } } else {