According to the adapter interrupt comes from PMIC GPIO 0, and
SCU firmware will take care battery charge/discharge scenario.
This patch add adapter interrupt handler, and remove charger 
relative function.

Signed-off-by: Major Lee <[email protected]>
---
 intel_mid_battery.c |  147
+++++++++++++++++++++++-----------------------------
 1 file changed, 67 insertions(+), 80 deletions(-)

--- linux-2.6.37.6.bak/drivers/power/intel_mid_battery.c
2011-04-12 10:00:03.120483277 +0800
+++ linux-2.6.37.6/drivers/power/intel_mid_battery.c    2011-04-18
17:00:09.756836000 +0800
@@ -33,6 +33,7 @@
 #include <linux/spi/spi.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
+#include <linux/gpio.h>
 
 #include <asm/intel_scu_ipc.h>
 
@@ -65,16 +66,6 @@ MODULE_PARM_DESC(debug, "Flag to enable 
 #define PMIC_BATT_ADC_ACCCHRG_MASK     (1 << 31)
 #define PMIC_BATT_ADC_ACCCHRGVAL_MASK  0x7FFFFFFF
 
-/* pmic ipc related */
-#define PMIC_BATT_CHR_IPC_FCHRG_SUBID  0x4
-#define PMIC_BATT_CHR_IPC_TCHRG_SUBID  0x6
-
-/* types of battery charging */
-enum batt_charge_type {
-       BATT_USBOTG_500MA_CHARGE,
-       BATT_USBOTG_TRICKLE_CHARGE,
-};
-
 /* valid battery events */
 enum batt_event {
        BATT_EVENT_BATOVP_EXCPT,
@@ -109,9 +100,11 @@ struct pmic_power_module_info {
        struct power_supply usb;
        struct power_supply batt;
        int irq;                                /* GPE_ID or IRQ# */
+       int adap_irq;
        struct workqueue_struct *monitor_wqueue;
        struct delayed_work monitor_battery;
        struct work_struct handler;
+       struct work_struct adap_handler;
 };
 
 static unsigned int delay_time = 2000; /* in ms */
@@ -156,6 +149,9 @@ struct battery_property {
 #define IPC_CMD_CC_RD            1 /* Read coulomb counter value */
 #define IPC_CMD_BATTERY_PROPERTY  2 /* Read Battery property */
 
+/* PMIC_GPIO_0 for adapter detection */
+#define PMIC_GPIO_0                    64
+
 /**
  *     pmic_scu_ipc_battery_cc_read    -       read battery cc
  *     @value: battery coulomb counter read
@@ -199,18 +195,6 @@ static int pmic_scu_ipc_battery_property
 }
 
 /**
- *     pmic_scu_ipc_set_charger        -       set charger
- *     @charger: charger to select
- *
- *     Switch the charging mode for the SCU
- */
-
-static int pmic_scu_ipc_set_charger(int charger)
-{
-       return intel_scu_ipc_simple_command(IPCMSG_BATTERY, charger);
-}
-
-/**
  * pmic_battery_log_event - log battery events
  * @event: battery event to be logged
  * Context: can sleep
@@ -494,40 +478,41 @@ static void pmic_battery_monitor(struct 
 }
 
 /**
- * pmic_battery_set_charger - set battery charger
- * @pbi: device info structure
- * @chrg: charge mode to set battery charger in
- * Context: can sleep
+ * pmic_adapter_interrupt_handler - pmic adapter interrupt handler
+ * Context: interrupt context
  *
- * PMIC battery charger needs to be enabled based on the usb charge
- * capabilities connected to the platform.
+ * PMIC adapter interrupt handler which will be called with apapter
+ * connected or removed condition occurs.
  */
-static int pmic_battery_set_charger(struct pmic_power_module_info *pbi,
-                                               enum batt_charge_type
chrg)
+static irqreturn_t pmic_adapter_interrupt_handler(int id, void *dev)
 {
-       int retval;
+       struct pmic_power_module_info *pbi = dev;
 
-       /* set usblmt bits and chrgcntl register bits appropriately */
-       switch (chrg) {
-       case BATT_USBOTG_500MA_CHARGE:
-               retval =
pmic_scu_ipc_set_charger(PMIC_BATT_CHR_IPC_FCHRG_SUBID);
-               break;
-       case BATT_USBOTG_TRICKLE_CHARGE:
-               retval =
pmic_scu_ipc_set_charger(PMIC_BATT_CHR_IPC_TCHRG_SUBID);
-               break;
-       default:
-               dev_warn(pbi->dev, "%s(): out of range usb charger "
-                                               "charge detected\n",
__func__);
-               return -EINVAL;
-       }
+       schedule_work(&pbi->adap_handler);
 
-       if (retval) {
-               dev_warn(pbi->dev, "%s(): ipc pmic read failed\n",
-
__func__);
-               return retval;;
-       }
+       return IRQ_HANDLED;
+}
 
-       return 0;
+/**
+ * pmic_adaptor_handle_intrpt - pmic adapter service interrupt
+ * @work: work structure
+ * Context: can sleep
+ *
+ * PMIC adapter needs to either update the adapter status as connected
+ * or removed.
+ */
+static void pmic_adaptor_handle_intrpt(struct work_struct *work)
+{
+       struct pmic_power_module_info *pbi = container_of(work,
+                               struct pmic_power_module_info, handler);
+       int val = gpio_get_value(PMIC_GPIO_0);
+
+       if (val) {
+               pbi->usb_is_present = PMIC_USB_PRESENT;
+       } else {
+               pbi->usb_is_present = PMIC_USB_NOT_PRESENT;
+               pbi->usb_health = POWER_SUPPLY_HEALTH_UNKNOWN;
+       }
 }
 
 /**
@@ -561,7 +546,6 @@ static void pmic_battery_handle_intrpt(s
 {
        struct pmic_power_module_info *pbi = container_of(work,
                                struct pmic_power_module_info, handler);
-       enum batt_charge_type chrg;
        u8 r8;
 
        if (intel_scu_ipc_ioread8(PMIC_BATT_CHR_SCHRGINT_ADDR, &r8)) {
@@ -611,35 +595,6 @@ static void pmic_battery_handle_intrpt(s
                pbi->usb_health = POWER_SUPPLY_HEALTH_UNKNOWN;
                return;
        }
-
-       /* setup battery charging */
-
-#if 0
-       /* check usb otg power capability and set charger accordingly */
-       retval = langwell_udc_maxpower(&power);
-       if (retval) {
-               dev_warn(pbi->dev,
-                   "%s(): usb otg power query failed with error code
%d\n",
-                       __func__, retval);
-               return;
-       }
-
-       if (power >= 500)
-               chrg = BATT_USBOTG_500MA_CHARGE;
-       else
-#endif
-               chrg = BATT_USBOTG_TRICKLE_CHARGE;
-
-       /* enable battery charging */
-       if (pmic_battery_set_charger(pbi, chrg)) {
-               dev_warn(pbi->dev,
-                       "%s(): failed to set up battery charging\n",
__func__);
-               return;
-       }
-
-       dev_dbg(pbi->dev,
-               "pmic-battery: %s() - setting up battery charger
successful\n",
-                       __func__);
 }
 
 /**
@@ -667,10 +622,29 @@ static __devinit int probe(int irq, stru
 
        pbi->dev = dev;
        pbi->irq = irq;
+
+       /* It is better passed from platform data */
+       retval = gpio_request(PMIC_GPIO_0, "pmic-adap");
+       if (retval) {
+               dev_err(dev, "%s: request gpio fail\n", __func__);
+               goto gpio_failed;
+       }
+       retval = gpio_direction_input(PMIC_GPIO_0);
+       if (retval) {
+               dev_err(dev, "%s: set gpio direction fail\n", __func__);
+               goto gpio_failed;
+       }
+       pbi->adap_irq = gpio_to_irq(PMIC_GPIO_0);
+       if (pbi->adap_irq < 0) {
+               dev_err(dev, "%s: gpio to irq fail\n", __func__);
+               goto gpio_failed;
+       }
+
        dev_set_drvdata(dev, pbi);
 
        /* initialize all required framework before enabling interrupts
*/
        INIT_WORK(&pbi->handler, pmic_battery_handle_intrpt);
+       INIT_WORK(&pbi->adap_handler, pmic_adaptor_handle_intrpt);
        INIT_DELAYED_WORK(&pbi->monitor_battery, pmic_battery_monitor);
        pbi->monitor_wqueue =
                        create_singlethread_workqueue(dev_name(dev));
@@ -688,6 +662,14 @@ static __devinit int probe(int irq, stru
                goto requestirq_failed;
        }
 
+       /* register adaptor interrupt */
+       retval = request_irq(pbi->adap_irq,
pmic_adapter_interrupt_handler,
+
IRQ_TYPE_EDGE_BOTH, "pmic-usb", pbi);
+       if (retval) {
+               dev_err(dev, "%s: cannot get adaptor irq\n", __func__);
+               goto requestirq_failed_adap;
+       }
+
        /* register pmic-batt with power supply subsystem */
        pbi->batt.name = "pmic-batt";
        pbi->batt.type = POWER_SUPPLY_TYPE_BATTERY;
@@ -734,9 +716,13 @@ power_reg_failed_1:
 power_reg_failed:
        cancel_rearming_delayed_workqueue(pbi->monitor_wqueue,
                                                &pbi->monitor_battery);
+       free_irq(pbi->adap_irq, pbi);
+requestirq_failed_adap:
+       free_irq(pbi->irq, pbi);
 requestirq_failed:
        destroy_workqueue(pbi->monitor_wqueue);
 wqueue_failed:
+gpio_failed:
        kfree(pbi);
 
        return retval;
@@ -762,6 +748,7 @@ static int __devexit platform_pmic_batte
        struct pmic_power_module_info *pbi =
dev_get_drvdata(&pdev->dev);
 
        free_irq(pbi->irq, pbi);
+       free_irq(pbi->adap_irq, pbi);
        cancel_rearming_delayed_workqueue(pbi->monitor_wqueue,
                                        &pbi->monitor_battery);
        destroy_workqueue(pbi->monitor_wqueue);

Attachment: intel_mid_battery-add-adapter-interrupt-and-remove-charger-function.patch
Description: intel_mid_battery-add-adapter-interrupt-and-remove-charger-function.patch

_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to