drm/i915: SDVO hotplug have different interrupt status bits for i915/i965/g4x
[linux-2.6.git] / drivers / power / max8925_power.c
index 8e5aec2..daa333b 100644 (file)
@@ -78,6 +78,8 @@ struct max8925_power_info {
        unsigned                batt_detect:1;  /* detecing MB by ID pin */
        unsigned                topoff_threshold:2;
        unsigned                fast_charge:3;
+       unsigned                no_temp_support:1;
+       unsigned                no_insert_detect:1;
 
        int (*set_charger) (int);
 };
@@ -116,17 +118,7 @@ static irqreturn_t max8925_charger_handler(int irq, void *data)
        case MAX8925_IRQ_VCHG_DC_F:
                info->ac_online = 0;
                __set_charger(info, 0);
-               dev_dbg(chip->dev, "Adapter is removal\n");
-               break;
-       case MAX8925_IRQ_VCHG_USB_R:
-               info->usb_online = 1;
-               __set_charger(info, 1);
-               dev_dbg(chip->dev, "USB inserted\n");
-               break;
-       case MAX8925_IRQ_VCHG_USB_F:
-               info->usb_online = 0;
-               __set_charger(info, 0);
-               dev_dbg(chip->dev, "USB is removal\n");
+               dev_dbg(chip->dev, "Adapter removed\n");
                break;
        case MAX8925_IRQ_VCHG_THM_OK_F:
                /* Battery is not ready yet */
@@ -168,27 +160,33 @@ static irqreturn_t max8925_charger_handler(int irq, void *data)
 static int start_measure(struct max8925_power_info *info, int type)
 {
        unsigned char buf[2] = {0, 0};
+       int meas_cmd;
        int meas_reg = 0, ret;
 
        switch (type) {
        case MEASURE_VCHG:
+               meas_cmd = MAX8925_CMD_VCHG;
                meas_reg = MAX8925_ADC_VCHG;
                break;
        case MEASURE_VBBATT:
+               meas_cmd = MAX8925_CMD_VBBATT;
                meas_reg = MAX8925_ADC_VBBATT;
                break;
        case MEASURE_VMBATT:
+               meas_cmd = MAX8925_CMD_VMBATT;
                meas_reg = MAX8925_ADC_VMBATT;
                break;
        case MEASURE_ISNS:
+               meas_cmd = MAX8925_CMD_ISNS;
                meas_reg = MAX8925_ADC_ISNS;
                break;
        default:
                return -EINVAL;
        }
 
+       max8925_reg_write(info->adc, meas_cmd, 0);
        max8925_bulk_read(info->adc, meas_reg, 2, buf);
-       ret = (buf[0] << 4) | (buf[1] >> 4);
+       ret = ((buf[0]<<8) | buf[1]) >> 4;
 
        return ret;
 }
@@ -208,7 +206,7 @@ static int max8925_ac_get_prop(struct power_supply *psy,
                if (info->ac_online) {
                        ret = start_measure(info, MEASURE_VCHG);
                        if (ret >= 0) {
-                               val->intval = ret << 1; /* unit is mV */
+                               val->intval = ret * 2000;       /* unit is uV */
                                goto out;
                        }
                }
@@ -242,7 +240,7 @@ static int max8925_usb_get_prop(struct power_supply *psy,
                if (info->usb_online) {
                        ret = start_measure(info, MEASURE_VCHG);
                        if (ret >= 0) {
-                               val->intval = ret << 1; /* unit is mV */
+                               val->intval = ret * 2000;       /* unit is uV */
                                goto out;
                        }
                }
@@ -266,7 +264,6 @@ static int max8925_bat_get_prop(struct power_supply *psy,
                                union power_supply_propval *val)
 {
        struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
-       long long int tmp = 0;
        int ret = 0;
 
        switch (psp) {
@@ -277,7 +274,7 @@ static int max8925_bat_get_prop(struct power_supply *psy,
                if (info->bat_online) {
                        ret = start_measure(info, MEASURE_VMBATT);
                        if (ret >= 0) {
-                               val->intval = ret << 1; /* unit is mV */
+                               val->intval = ret * 2000;       /* unit is uV */
                                ret = 0;
                                break;
                        }
@@ -288,8 +285,8 @@ static int max8925_bat_get_prop(struct power_supply *psy,
                if (info->bat_online) {
                        ret = start_measure(info, MEASURE_ISNS);
                        if (ret >= 0) {
-                               tmp = (long long int)ret * 6250 / 4096 - 3125;
-                               ret = (int)tmp;
+                               /* assume r_sns is 0.02 */
+                               ret = ((ret * 6250) - 3125) /* uA */;
                                val->intval = 0;
                                if (ret > 0)
                                        val->intval = ret; /* unit is mA */
@@ -365,13 +362,14 @@ static __devinit int max8925_init_charger(struct max8925_chip *chip,
        int ret;
 
        REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp");
-       REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
-       REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
-       REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_OVP, "usb-ovp");
-       REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_F, "usb-remove");
-       REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_R, "usb-insert");
-       REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
-       REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
+       if (!info->no_insert_detect) {
+               REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
+               REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
+       }
+       if (!info->no_temp_support) {
+               REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
+               REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
+       }
        REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high");
        REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low");
        REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset");
@@ -379,9 +377,15 @@ static __devinit int max8925_init_charger(struct max8925_chip *chip,
        REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff");
        REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire");
 
-       info->ac_online = 0;
        info->usb_online = 0;
        info->bat_online = 0;
+
+       /* check for power - can miss interrupt at boot time */
+       if (start_measure(info, MEASURE_VCHG) * 2000 > 500000)
+               info->ac_online = 1;
+       else
+               info->ac_online = 0;
+
        ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
        if (ret >= 0) {
                /*
@@ -425,16 +429,11 @@ static __devexit int max8925_deinit_charger(struct max8925_power_info *info)
 static __devinit int max8925_power_probe(struct platform_device *pdev)
 {
        struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
-       struct max8925_platform_data *max8925_pdata;
        struct max8925_power_pdata *pdata = NULL;
        struct max8925_power_info *info;
        int ret;
 
-       if (pdev->dev.parent->platform_data) {
-               max8925_pdata = pdev->dev.parent->platform_data;
-               pdata = max8925_pdata->power;
-       }
-
+       pdata = pdev->dev.platform_data;
        if (!pdata) {
                dev_err(&pdev->dev, "platform data isn't assigned to "
                        "power supply\n");
@@ -447,12 +446,15 @@ static __devinit int max8925_power_probe(struct platform_device *pdev)
        info->chip = chip;
        info->gpm = chip->i2c;
        info->adc = chip->adc;
+       platform_set_drvdata(pdev, info);
 
        info->ac.name = "max8925-ac";
        info->ac.type = POWER_SUPPLY_TYPE_MAINS;
        info->ac.properties = max8925_ac_props;
        info->ac.num_properties = ARRAY_SIZE(max8925_ac_props);
        info->ac.get_property = max8925_ac_get_prop;
+       info->ac.supplied_to = pdata->supplied_to;
+       info->ac.num_supplicants = pdata->num_supplicants;
        ret = power_supply_register(&pdev->dev, &info->ac);
        if (ret)
                goto out;
@@ -463,6 +465,9 @@ static __devinit int max8925_power_probe(struct platform_device *pdev)
        info->usb.properties = max8925_usb_props;
        info->usb.num_properties = ARRAY_SIZE(max8925_usb_props);
        info->usb.get_property = max8925_usb_get_prop;
+       info->usb.supplied_to = pdata->supplied_to;
+       info->usb.num_supplicants = pdata->num_supplicants;
+
        ret = power_supply_register(&pdev->dev, &info->usb);
        if (ret)
                goto out_usb;
@@ -482,8 +487,8 @@ static __devinit int max8925_power_probe(struct platform_device *pdev)
        info->topoff_threshold = pdata->topoff_threshold;
        info->fast_charge = pdata->fast_charge;
        info->set_charger = pdata->set_charger;
-       dev_set_drvdata(&pdev->dev, info);
-       platform_set_drvdata(pdev, info);
+       info->no_temp_support = pdata->no_temp_support;
+       info->no_insert_detect = pdata->no_insert_detect;
 
        max8925_init_charger(chip, info);
        return 0;
@@ -518,17 +523,7 @@ static struct platform_driver max8925_power_driver = {
        },
 };
 
-static int __init max8925_power_init(void)
-{
-       return platform_driver_register(&max8925_power_driver);
-}
-module_init(max8925_power_init);
-
-static void __exit max8925_power_exit(void)
-{
-       platform_driver_unregister(&max8925_power_driver);
-}
-module_exit(max8925_power_exit);
+module_platform_driver(max8925_power_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Power supply driver for MAX8925");