From patchwork Mon Jul 26 08:30:43 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wayne Lin <00601wayne@gmail.com> X-Patchwork-Id: 114239 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6Q8XEhR032210 for ; Mon, 26 Jul 2010 08:33:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753994Ab0GZIdm (ORCPT ); Mon, 26 Jul 2010 04:33:42 -0400 Received: from mail-pv0-f174.google.com ([74.125.83.174]:46745 "EHLO mail-pv0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754043Ab0GZIdl (ORCPT ); Mon, 26 Jul 2010 04:33:41 -0400 Received: by mail-pv0-f174.google.com with SMTP id 7so4321238pvc.19 for ; Mon, 26 Jul 2010 01:33:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=+CkKCcget5lussELWeMvS3UfwCV7o5669XPpt4yk1QI=; b=IjiwnRjjg4F+qzzGDHFrg7ATs68/+nIDML2qQXXJHW/EAbw+3+nYMXbpgZvojryu3u PD3DkvMHuvXL7rdqIq9faO0nbvp+zURP0gc3VXut/Ow53a1evwW3uJd1oomXKns9jD+2 1hmmtmXCI4+zmgLF03gUYLLaBnAcYIOMQYXZo= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=U3u4tRttIh0XEkbclQqRrpKG0/WiNqbhfIeoLISKrrMLsw/rhAiVKBXHayODaTPPMq 5O9HDvKUJAgaqtavE1+iWpG2CSUqR3juRGbZS0G0WGnuvGeibWgH7nLXERK/w55uayuS lMd01ZGVaIcxP58I8KVHMq9tfoH3P2pjSt2cQ= Received: by 10.142.207.9 with SMTP id e9mr8642679wfg.172.1280133221594; Mon, 26 Jul 2010 01:33:41 -0700 (PDT) Received: from localhost.localdomain (60-250-56-66.HINET-IP.hinet.net [60.250.56.66]) by mx.google.com with ESMTPS id w27sm3846304wfd.5.2010.07.26.01.33.39 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 26 Jul 2010 01:33:41 -0700 (PDT) From: Wayne Lin <00601wayne@gmail.com> To: linux-input@vger.kernel.org Cc: wayne Subject: [RFC 34/36] [Driver][Qualcomm 1070][EC_BAT] Adding newer version battery driver Date: Mon, 26 Jul 2010 16:30:43 +0800 Message-Id: <1280133045-25945-34-git-send-email-wayne.lin@quantatw.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1280133045-25945-1-git-send-email-wayne.lin@quantatw.com> References: <1280133045-25945-1-git-send-email-wayne.lin@quantatw.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 26 Jul 2010 08:33:43 +0000 (UTC) diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index c837ba8..c1b21d2 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -112,7 +112,7 @@ config CHARGER_PCF50633 config BATTERY_QCIBAT tristate "Quanta Computer Inc. Battery" - depends on SENSORS_WPCE775X && ARCH_MSM_SCORPION + depends on SENSORS_NPCE781X && ARCH_MSM_SCORPION default n help Say Y here if you want to use the Quanta battery driver for ST15 diff --git a/drivers/power/qci_battery.c b/drivers/power/qci_battery.c index 593d720..2d1f052 100644 --- a/drivers/power/qci_battery.c +++ b/drivers/power/qci_battery.c @@ -1,356 +1,325 @@ -/* Quanta I2C Battery Driver - * - * Copyright (C) 2009 Quanta Computer Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -/* - * - * The Driver with I/O communications via the I2C Interface for ST15 platform. - * And it is only working on the nuvoTon WPCE775x Embedded Controller. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qci_battery.h" - -struct qci_bat_info { - u8 type_id; - u8 power_flag; - u8 ec_ver_lsb; - u8 ec_ver_msb; - u8 mbat_rsoc; - u8 mbat_volt_lsb; - u8 mbat_volt_msb; - u8 mbat_status; - u8 mbchg_status; - u8 mbat_temp_lsb; - u8 mbat_temp_msb; -}; - -/* General structure to hold the driver data */ -struct i2cbat_drv_data { - struct i2c_client *bi2c_client; - struct work_struct work; - char batt_data[I2C_BAT_BUFFER_LEN+1]; - unsigned int qcibat_irq; - unsigned int qcibat_gpio; - struct qci_bat_info bif; -}; - -static struct i2cbat_drv_data context; -/********************************************************************* - * Power - *********************************************************************/ - -static int qci_ac_get_prop(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - int ret = 0; - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: - if (context.bif.power_flag & EC_FLAG_ADAPTER_IN) - val->intval = EC_ADAPTER_PRESENT; - else - val->intval = EC_ADAPTER_NOT_PRESENT; - break; - default: - ret = -EINVAL; - break; - } - return ret; -} - -static enum power_supply_property qci_ac_props[] = { - POWER_SUPPLY_PROP_ONLINE, -}; - -static enum power_supply_property qci_bat_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_HEALTH, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_VOLTAGE_AVG, - POWER_SUPPLY_PROP_CURRENT_AVG, - POWER_SUPPLY_PROP_CAPACITY, - POWER_SUPPLY_PROP_TEMP, - POWER_SUPPLY_PROP_TEMP_AMBIENT, - POWER_SUPPLY_PROP_MANUFACTURER, - POWER_SUPPLY_PROP_SERIAL_NUMBER, - POWER_SUPPLY_PROP_CHARGE_COUNTER, -}; - -static int qbat_get_status(union power_supply_propval *val) -{ - if ((context.bif.mbat_status & MAIN_BATTERY_STATUS_BAT_IN) == 0x0) - val->intval = POWER_SUPPLY_STATUS_UNKNOWN; - else if (context.bif.mbchg_status & CHG_STATUS_BAT_INCHARGE) - val->intval = POWER_SUPPLY_STATUS_CHARGING; - else if (context.bif.mbat_status & MAIN_BATTERY_STATUS_BAT_FULL) - val->intval = POWER_SUPPLY_STATUS_FULL; - else - val->intval = POWER_SUPPLY_STATUS_DISCHARGING; - - return 0; -} - -static int qbat_get_present(union power_supply_propval *val) -{ - if (context.bif.mbat_status & MAIN_BATTERY_STATUS_BAT_IN) - val->intval = EC_BAT_PRESENT; - else - val->intval = EC_BAT_NOT_PRESENT; - return 0; -} - -static int qbat_get_health(union power_supply_propval *val) -{ - if ((context.bif.mbat_status & MAIN_BATTERY_STATUS_BAT_IN) == 0x0) - val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; - else - val->intval = POWER_SUPPLY_HEALTH_GOOD; - return 0; -} - -static int qbat_get_voltage_avg(union power_supply_propval *val) -{ - val->intval = (context.bif.mbat_volt_msb << 8 | - context.bif.mbat_volt_lsb); - return 0; -} - -static int qbat_get_capacity(union power_supply_propval *val) -{ - if ((context.bif.mbat_status & MAIN_BATTERY_STATUS_BAT_IN) == 0x0) - val->intval = 0xFF; - else - val->intval = context.bif.mbat_rsoc; - return 0; -} - -static int qbat_get_temp_avg(union power_supply_propval *val) -{ - if ((context.bif.mbat_status & MAIN_BATTERY_STATUS_BAT_IN) == 0x0) - val->intval = 0xFFFF; - else - val->intval = ((context.bif.mbat_temp_msb << 8) | - context.bif.mbat_temp_lsb) - 2731; - return 0; -} - -static int qbat_get_mfr(union power_supply_propval *val) -{ - val->strval = "Unknown"; - return 0; -} - -static int qbat_get_tech(union power_supply_propval *val) -{ - if ((context.bif.mbat_status & MAIN_BATTERY_STATUS_BAT_IN) == 0x0) - val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; - else - val->intval = POWER_SUPPLY_TECHNOLOGY_LION; - return 0; -} - -/********************************************************************* - * Battery properties - *********************************************************************/ -static int qbat_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - int ret = 0; - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - ret = qbat_get_status(val); - break; - case POWER_SUPPLY_PROP_PRESENT: - ret = qbat_get_present(val); - break; - case POWER_SUPPLY_PROP_HEALTH: - ret = qbat_get_health(val); - break; - case POWER_SUPPLY_PROP_MANUFACTURER: - ret = qbat_get_mfr(val); - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - ret = qbat_get_tech(val); - break; - case POWER_SUPPLY_PROP_VOLTAGE_AVG: - ret = qbat_get_voltage_avg(val); - break; - case POWER_SUPPLY_PROP_CURRENT_AVG: - break; - case POWER_SUPPLY_PROP_CAPACITY: - ret = qbat_get_capacity(val); - break; - case POWER_SUPPLY_PROP_TEMP: - ret = qbat_get_temp_avg(val); - break; - case POWER_SUPPLY_PROP_TEMP_AMBIENT: - ret = qbat_get_temp_avg(val); - break; - case POWER_SUPPLY_PROP_CHARGE_COUNTER: - break; - case POWER_SUPPLY_PROP_SERIAL_NUMBER: - break; - default: - ret = -EINVAL; - break; - } - - return ret; -} - -/********************************************************************* - * Initialisation - *********************************************************************/ - -static struct power_supply qci_ac = { - .name = "ac", - .type = POWER_SUPPLY_TYPE_MAINS, - .properties = qci_ac_props, - .num_properties = ARRAY_SIZE(qci_ac_props), - .get_property = qci_ac_get_prop, -}; - -static struct power_supply qci_bat = { - .name = "battery", - .type = POWER_SUPPLY_TYPE_BATTERY, - .properties = qci_bat_props, - .num_properties = ARRAY_SIZE(qci_bat_props), - .get_property = qbat_get_property, - .use_for_apm = 1, -}; - -static irqreturn_t qbat_interrupt(int irq, void *dev_id) -{ - struct i2cbat_drv_data *ibat_drv_data = dev_id; - schedule_work(&ibat_drv_data->work); - return IRQ_HANDLED; -} - -static int qci_get_bat_info(struct i2c_client *client, char *ec_data) -{ - struct i2c_msg bat_msg; - bat_msg.addr = client->addr; - bat_msg.flags = I2C_M_RD; - bat_msg.len = I2C_BAT_BUFFER_LEN; - bat_msg.buf = ec_data; - return i2c_transfer(client->adapter, &bat_msg, 1); -} - -static void qbat_work(struct work_struct *_work) -{ - struct i2cbat_drv_data *ibat_drv_data = - container_of(_work, struct i2cbat_drv_data, work); - struct i2c_client *ibatclient = ibat_drv_data->bi2c_client; - - qci_get_bat_info(ibatclient, ibat_drv_data->batt_data); - memcpy(&context.bif, - ibat_drv_data->batt_data, - sizeof(struct qci_bat_info)); - power_supply_changed(&qci_ac); - power_supply_changed(&qci_bat); -} - -static struct platform_device *bat_pdev; - -static int __init qbat_init(void) -{ - int err = 0; - - context.bi2c_client = wpce_get_i2c_client(); - if (context.bi2c_client == NULL) - return -1; - - i2c_set_clientdata(context.bi2c_client, &context); - context.qcibat_gpio = context.bi2c_client->irq; - - /*battery device register*/ - bat_pdev = platform_device_register_simple("battery", 0, NULL, 0); - if (IS_ERR(bat_pdev)) - return PTR_ERR(bat_pdev); - - err = power_supply_register(&bat_pdev->dev, &qci_ac); - if (err) - goto ac_failed; - - qci_bat.name = bat_pdev->name; - err = power_supply_register(&bat_pdev->dev, &qci_bat); - if (err) - goto battery_failed; - - /*battery irq configure*/ - INIT_WORK(&context.work, qbat_work); - err = gpio_request(context.qcibat_gpio, "qci-bat"); - if (err) { - dev_err(&context.bi2c_client->dev, - "[BAT] err gpio request\n"); - goto gpio_request_fail; - } - context.qcibat_irq = gpio_to_irq(context.qcibat_gpio); - err = request_irq(context.qcibat_irq, qbat_interrupt, - IRQF_TRIGGER_FALLING, BATTERY_ID_NAME, &context); - if (err) { - dev_err(&context.bi2c_client->dev, - "[BAT] unable to get IRQ\n"); - goto request_irq_fail; - } - err = qci_get_bat_info(context.bi2c_client, context.batt_data); - - goto success; - -request_irq_fail: - gpio_free(context.qcibat_gpio); - -gpio_request_fail: - power_supply_unregister(&qci_bat); - -battery_failed: - power_supply_unregister(&qci_ac); - -ac_failed: - platform_device_unregister(bat_pdev); - - i2c_set_clientdata(context.bi2c_client, NULL); -success: - return err; -} - -static void __exit qbat_exit(void) -{ - free_irq(context.qcibat_irq, &context); - gpio_free(context.qcibat_gpio); - power_supply_unregister(&qci_bat); - power_supply_unregister(&qci_ac); - platform_device_unregister(bat_pdev); - i2c_set_clientdata(context.bi2c_client, NULL); -} - -late_initcall(qbat_init); -module_exit(qbat_exit); - -MODULE_AUTHOR("Quanta Computer Inc."); -MODULE_DESCRIPTION("Quanta Embedded Controller I2C Battery Driver"); -MODULE_LICENSE("GPL v2"); - +/* Quanta I2C Battery Driver + * + * Copyright (C) 2009 Quanta Computer Inc. + * Author: Austin Lai + * Author: Hsin Wu + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + + /* + * + * The Driver with I/O communications via the I2C Interface of LCBU. + * And it is only working on the nuvoTon NPCE781L Embedded Controller. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "qci_battery.h" + +struct qci_bat_status { + + u8 battery_state; + u16 battery_present_rate; + u16 battery_remaining_capacity; + u16 battery_present_voltage; + u8 battery_rsoc; + u16 battery_average_current; + u16 battery_temperature; +} bst; + +struct qci_ac_status { + u8 power_source; +} psr; + +/* General structure to hold the driver data */ +struct i2cbat_drv_data { + struct i2c_client *bi2c_client; + struct work_struct work; + char batt_data[I2C_BAT_BUFFER_LEN+1]; + unsigned int qcibat_irq; + unsigned int qcibat_gpio; +}; + +/********************************************************************* + * Power + *********************************************************************/ + +static int qci_ac_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + unsigned char psr; + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + + psr = npce_read_ecram(ECRAM_POWER_SOURCE); + + if (psr & EC_FLAG_ADAPTER_IN) + val->intval = EC_ADAPTER_PRESENT; + else + val->intval = EC_ADAPTER_NOT_PRESENT; + break; + + default: + ret = -EINVAL; + break; + } + return ret; +} + +static enum power_supply_property qci_ac_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static enum power_supply_property qci_bat_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_VOLTAGE_AVG, + POWER_SUPPLY_PROP_CURRENT_AVG, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_TEMP, +}; + +static int qbat_get_status(union power_supply_propval *val, uint8_t ec_byte) +{ + if (!(bst.battery_state & MAIN_BATTERY_STATUS_BAT_IN)) + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; + else if (bst.battery_state & MAIN_BATTERY_STATUS_BAT_CHARGING) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else if (bst.battery_state & MAIN_BATTERY_STATUS_BAT_FULL) + val->intval = POWER_SUPPLY_STATUS_FULL; + else if (bst.battery_state & MAIN_BATTERY_STATUS_BAT_DISCHRG) + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + return 0; +} + +static int qbat_get_present(union power_supply_propval *val, uint16_t ec_word) +{ + if (bst.battery_state & MAIN_BATTERY_STATUS_BAT_IN) + val->intval = EC_BAT_PRESENT; + else + val->intval = EC_BAT_NOT_PRESENT; + return 0; +} + +static int qbat_get_voltage_avg(union power_supply_propval *val, uint16_t ec_word) +{ + val->intval = bst.battery_present_voltage; + return 0; +} + +static int qbat_get_capacity(union power_supply_propval *val, uint8_t ec_byte) +{ + val->intval = bst.battery_rsoc; + return 0; +} + +static int qbat_get_current_avg(union power_supply_propval *val, uint16_t ec_word) +{ + val->intval = bst.battery_average_current; + return 0; +} + +static int qbat_get_temp_avg(union power_supply_propval *val, uint16_t ec_word) +{ + val->intval = (bst.battery_temperature - 2730)/10; + return 0; +} + +/********************************************************************* + * Battery properties + *********************************************************************/ +static int qbat_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + int16_t ec_word = 0; + uint8_t ec_byte = 0; + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + ret = qbat_get_status(val, ec_byte); + break; + case POWER_SUPPLY_PROP_PRESENT: + ret = qbat_get_present(val, ec_word); + break; + case POWER_SUPPLY_PROP_VOLTAGE_AVG: + ret = qbat_get_voltage_avg(val, ec_word); + break; + case POWER_SUPPLY_PROP_CAPACITY: + ret = qbat_get_capacity(val, ec_byte); + break; + case POWER_SUPPLY_PROP_CURRENT_AVG: + ret = qbat_get_current_avg(val, ec_word); + break; + case POWER_SUPPLY_PROP_TEMP: + ret = qbat_get_temp_avg(val, ec_word); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/********************************************************************* + * Initialisation + *********************************************************************/ + +static struct power_supply qci_ac = { + .name = "ac", + .type = POWER_SUPPLY_TYPE_MAINS, + .properties = qci_ac_props, + .num_properties = ARRAY_SIZE(qci_ac_props), + .get_property = qci_ac_get_prop, +}; + +static struct power_supply qci_bat = { + .properties = qci_bat_props, + .num_properties = ARRAY_SIZE(qci_bat_props), + .get_property = qbat_get_property, + .use_for_apm = 1, +}; + +static irqreturn_t qbat_interrupt(int irq, void *dev_id) +{ + struct i2cbat_drv_data *ibat_drv_data = dev_id; + schedule_work(&ibat_drv_data->work); + return IRQ_HANDLED; +} + +static int qci_bat_status(struct i2c_client *client, char *ec_data) +{ + struct i2c_msg bat_msg; + + npce_set_ecram_index(ECRAM_BATTERY_STATUS); + + bat_msg.addr = client->addr; + bat_msg.flags = I2C_M_RD; + bat_msg.len = I2C_BAT_BUFFER_LEN; + bat_msg.buf = ec_data; + return i2c_transfer(client->adapter, &bat_msg, 1); +} + +static void qbat_work(struct work_struct *_work) +{ + struct i2cbat_drv_data *ibat_drv_data = + container_of(_work, struct i2cbat_drv_data, work); + struct i2c_client *ibatclient = ibat_drv_data->bi2c_client; + + qci_bat_status(ibatclient, ibat_drv_data->batt_data); + bst.battery_state = ibat_drv_data->batt_data[0]; + bst.battery_present_rate = (ibat_drv_data->batt_data[2]<<8) | + (ibat_drv_data->batt_data[1]); + bst.battery_remaining_capacity = (ibat_drv_data->batt_data[4]<<8) | + (ibat_drv_data->batt_data[3]); + bst.battery_present_voltage = (ibat_drv_data->batt_data[6]<<8) | + (ibat_drv_data->batt_data[5]); + bst.battery_rsoc = ibat_drv_data->batt_data[7]; + bst.battery_average_current = (ibat_drv_data->batt_data[9]<<8) | + (ibat_drv_data->batt_data[8]); + bst.battery_temperature = (ibat_drv_data->batt_data[11]<<8) | + (ibat_drv_data->batt_data[10]); + power_supply_changed(&qci_ac); + power_supply_changed(&qci_bat); + return ; +} + +static struct platform_device *bat_pdev; + +static int __init qbat_init(void) +{ + int err = 0; + struct i2cbat_drv_data *context = 0; + context = kzalloc(sizeof(struct i2cbat_drv_data), GFP_KERNEL); + if (!context) + return err; + context->bi2c_client = npce_get_i2c_client(); + + i2c_set_clientdata(context->bi2c_client, context); + context->qcibat_gpio = BATTERY_INT_GPIO; + + /*battery device register*/ + bat_pdev = platform_device_register_simple("battery", 0, NULL, 0); + if (IS_ERR(bat_pdev)) + { + kfree(context); + return PTR_ERR(bat_pdev); + } + + err = power_supply_register(&bat_pdev->dev, &qci_ac); + if (err) + goto ac_failed; + + qci_bat.name = bat_pdev->name; + err = power_supply_register(&bat_pdev->dev, &qci_bat); + if (err) + goto battery_failed; + + /*battery irq configure*/ + INIT_WORK(&context->work, qbat_work); + err = gpio_request(context->qcibat_gpio, "qci-bat"); + if (err) { + pr_err("[BAT] err gpio request\n"); + goto gpio_request_fail; + } + context->qcibat_irq = gpio_to_irq(context->qcibat_gpio); + err = request_irq(context->qcibat_irq, qbat_interrupt, + IRQF_TRIGGER_FALLING, BATTERY_ID_NAME, context); + if (err) { + pr_err("[BAT] unable to get IRQ\n"); + goto request_irq_fail; + } + err = qci_bat_status(context->bi2c_client, context->batt_data); + + goto success; + +request_irq_fail: + gpio_free(context->qcibat_gpio); + +gpio_request_fail: + power_supply_unregister(&qci_bat); + +battery_failed: + power_supply_unregister(&qci_ac); + +ac_failed: + platform_device_unregister(bat_pdev); + + i2c_set_clientdata(context->bi2c_client, NULL); + kfree(context); +success: + return err; +} + +static void __exit qbat_exit(void) +{ + power_supply_unregister(&qci_bat); + power_supply_unregister(&qci_ac); + platform_device_unregister(bat_pdev); +} + +late_initcall(qbat_init); +module_exit(qbat_exit); + +MODULE_AUTHOR("Quanta Computer Inc."); +MODULE_DESCRIPTION("Quanta Embedded Controller I2C Battery Driver"); +MODULE_LICENSE("GPL v2"); + diff --git a/drivers/power/qci_battery.h b/drivers/power/qci_battery.h index abf55fb..5b0efe3 100644 --- a/drivers/power/qci_battery.h +++ b/drivers/power/qci_battery.h @@ -1,61 +1,67 @@ -/* Header file for Quanta I2C Battery Driver - * - * Copyright (C) 2009 Quanta Computer Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - - /* - * - * The Driver with I/O communications via the I2C Interface for ON2 of AP BU. - * And it is only working on the nuvoTon WPCE775x Embedded Controller. - * - */ - -#ifndef __QCI_BATTERY_H__ -#define __QCI_BATTERY_H__ - -#define BAT_I2C_ADDRESS 0x1A -#define BATTERY_ID_NAME "qci-i2cbat" -#define EC_FLAG_ADAPTER_IN 0x01 -#define EC_FLAG_POWER_ON 0x02 -#define EC_FLAG_ENTER_S3 0x04 -#define EC_FLAG_ENTER_S4 0x08 -#define EC_FLAG_IN_STANDBY 0x10 -#define EC_FLAG_SYSTEM_ON 0x20 -#define EC_FLAG_WAIT_HWPG 0x40 -#define EC_FLAG_S5_POWER_ON 0x80 - -#define MAIN_BATTERY_STATUS_BAT_IN 0x01 -#define MAIN_BATTERY_STATUS_BAT_FULL 0x02 -#define MAIN_BATTERY_STATUS_BAT_ABNORMAL 0x04 -#define MAIN_BATTERY_STATUS_BAT_CHARGING 0x08 -#define MAIN_BATTERY_STATUS_BAT_CRITICAL 0x10 -#define MAIN_BATTERY_STATUS_BAT_LOW 0x20 -#define MAIN_BATTERY_STATUS_BAT_DISCHRG 0x40 -#define MAIN_BATTERY_STATUS_BAT_SMB_VALID 0x80 - -#define CHG_STATUS_BAT_CHARGE 0x01 -#define CHG_STATUS_BAT_PRECHG 0x02 -#define CHG_STATUS_BAT_OVERTEMP 0x04 -#define CHG_STATUS_BAT_TYPE 0x08 -#define CHG_STATUS_BAT_GWROK 0x10 -#define CHG_STATUS_BAT_INCHARGE 0x20 -#define CHG_STATUS_BAT_WAKECHRG 0x40 -#define CHG_STATUS_BAT_CHGTIMEOUT 0x80 - -#define EC_ADAPTER_PRESENT 0x1 -#define EC_BAT_PRESENT 0x1 -#define EC_ADAPTER_NOT_PRESENT 0x0 -#define EC_BAT_NOT_PRESENT 0x0 -#define I2C_BAT_BUFFER_LEN 12 - -#endif +/* arm\mach-msm\include\mach\qci-battery.h + * Header file for Quanta I2C Battery Driver + * + * Copyright (C) 2009 Quanta Computer Inc. + * Author: Austin Lai + * Author: Hsin Wu + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + + /* + * + * The Driver with I/O communications via the I2C Interface for ON2 of AP BU. + * And it is only working on the nuvoTon NPCE781x Embedded Controller. + * + */ + +#ifndef __QCI_BATTERY_H__ +#define __QCI_BATTERY_H__ + +#define DEBUGMSG 0 /* debugging message */ + +#if DEBUGMSG +#define PRINTK(x...) printk(x) +#else +#define PRINTK(x...) +#endif + +#define ECRAM_POWER_SOURCE 0x40 +#define ECRAM_BATTERY_STATUS 0x82 + +#define EC_EVENT_BATTERY 0x01 +#define EC_EVENT_CHARGER 0x02 +#define EC_EVENT_SMBus 0x04 +#define EC_EVENT_AC 0x10 +#define EC_EVENT_TIMER 0x40 +#define EC_EVENT_LIDSW 0x80 + +#define BATTERY_ID_NAME "qci-i2cbat" +#define EC_FLAG_ADAPTER_IN 0x01 + +#define MAIN_BATTERY_STATUS_BAT_IN 0x08 +#define MAIN_BATTERY_STATUS_BAT_FULL 0x10 +#define MAIN_BATTERY_STATUS_BAT_CHARGING 0x02 +#define MAIN_BATTERY_STATUS_BAT_DISCHRG 0x01 + +#define EC_BAT_PRESENT 0x01 +#define EC_BAT_NOT_PRESENT 0x00 +#define EC_ADAPTER_PRESENT 0x01 +#define EC_ADAPTER_NOT_PRESENT 0x00 + +#define BATTERY_INT_GPIO 42 +#define I2C_BAT_BUFFER_LEN 12 /* max */ + +extern struct i2c_client *npce_get_i2c_client(void); +int npce_read_ecram(u8 ecram); +int npce_set_ecram_index(u8 ecram); + +#endif