From: Wayne Lin <00601wayne@gmail.com>
To: linux-input@vger.kernel.org
Cc: wayne <wayne.lin@quantatw.com>
Subject: [RFC 08/36] [Driver][Qualcomm 1070][EC_BAT] EC battery driver porting
Date: Mon, 26 Jul 2010 16:30:17 +0800 [thread overview]
Message-ID: <1280133045-25945-8-git-send-email-wayne.lin@quantatw.com> (raw)
In-Reply-To: <1280133045-25945-1-git-send-email-wayne.lin@quantatw.com>
From: wayne <wayne.lin@quantatw.com>
---
drivers/power/Kconfig | 8 +
drivers/power/Makefile | 1 +
drivers/power/qci_battery.c | 356 +++++++++++++++++++++++++++++++++++++++++++
drivers/power/qci_battery.h | 61 ++++++++
4 files changed, 426 insertions(+), 0 deletions(-)
create mode 100644 drivers/power/qci_battery.c
create mode 100644 drivers/power/qci_battery.h
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index cea6cef..c837ba8 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -110,4 +110,12 @@ config CHARGER_PCF50633
help
Say Y to include support for NXP PCF50633 Main Battery Charger.
+config BATTERY_QCIBAT
+ tristate "Quanta Computer Inc. Battery"
+ depends on SENSORS_WPCE775X && ARCH_MSM_SCORPION
+ default n
+ help
+ Say Y here if you want to use the Quanta battery driver for ST15
+ platform.
+
endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b96f29d..131fbe8 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
+obj-$(CONFIG_BATTERY_QCIBAT) += qci_battery.o
diff --git a/drivers/power/qci_battery.c b/drivers/power/qci_battery.c
new file mode 100644
index 0000000..593d720
--- /dev/null
+++ b/drivers/power/qci_battery.c
@@ -0,0 +1,356 @@
+/* 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 <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/sched.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/wpce775x.h>
+
+#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");
+
diff --git a/drivers/power/qci_battery.h b/drivers/power/qci_battery.h
new file mode 100644
index 0000000..abf55fb
--- /dev/null
+++ b/drivers/power/qci_battery.h
@@ -0,0 +1,61 @@
+/* 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
--
1.7.0.4
next prev parent reply other threads:[~2010-07-26 8:31 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-26 8:30 [RFC 01/36] [Driver][Qualcomm 1070][LCD] Resolve the booting to Chromium issue Wayne Lin
2010-07-26 8:30 ` [RFC 02/36] [Driver][Qualcomm 1070][USB] Register GPIO#109 for USB analog switch configuration Wayne Lin
2010-07-26 8:30 ` [RFC 04/36] [Driver][Qualcomm 1070][EC_KB] Adding new qci keyboard driver Wayne Lin
2010-07-26 8:55 ` Dmitry Torokhov
2010-07-26 11:16 ` Trilok Soni
2010-07-26 8:59 ` Datta, Shubhrajyoti
2010-07-26 8:30 ` [RFC 05/36] [Driver][Qualcomm 1070][TPM] Enable TPM module Wayne Lin
2010-07-26 8:30 ` [RFC 06/36] [Driver][Qualcomm 1070][EC_BRG] EC Bridge driver porting Wayne Lin
2010-07-26 8:30 ` [RFC 07/36] [Driver][Qualcomm 1070][EC_BRG] Enable EC Bridge Wayne Lin
2010-07-26 8:30 ` Wayne Lin [this message]
2010-07-26 8:30 ` [RFC 09/36] [Driver][Qualcomm 1070][EC_BAT] Enable EC battery Wayne Lin
2010-07-26 8:30 ` [RFC 11/36] [Driver][Qualcomm 1070][EC_G_SENSOR] Enable EC gravitation sensor Wayne Lin
2010-07-26 8:30 ` [RFC 12/36] [Driver][Qualcomm 1070][EC_C_SENSOR] EC compass sensor driver porting Wayne Lin
2010-07-26 8:30 ` [RFC 13/36] [Driver][Qualcomm 1070][EC_C_SENSOR] Enable EC compass sensor driver Wayne Lin
2010-07-26 8:30 ` [RFC 14/36] [Driver][Qualcomm 1070][CLOCK] Modify the AXI bus speed Wayne Lin
2010-07-26 8:30 ` [RFC 15/36] [Driver][Qualcomm 1070][VERSION] Adding version definition Wayne Lin
2010-07-26 8:30 ` [RFC 17/36] [Driver][Qualcomm 1070][WIFI/BT] Enable Athros WIFI driver Wayne Lin
2010-07-26 8:30 ` [RFC 18/36] [Driver][Qualcomm 1070][WIFI] Turn on the Athros WIFI power Wayne Lin
2010-07-26 8:30 ` [RFC 19/36] [Driver][Qualcomm 1070][BT] Enable Athros BT driver Wayne Lin
2010-07-26 8:30 ` [RFC 20/36] [Driver][Qualcomm 1070][WIFI/BT] Enable MMC1 dummy send read and configure Athros WIFI build-in driver Wayne Lin
2010-07-26 8:30 ` [RFC 21/36] Revert " [Driver][Qualcomm 1070][CLOCK] Modify the AXI bus speed" Wayne Lin
2010-07-26 8:46 ` Dmitry Torokhov
2010-07-26 8:30 ` [RFC 22/36] [Driver][Qualcomm 1070][CLOCK] Modify the AXI bus maximum speed Wayne Lin
2010-07-26 8:30 ` [RFC 23/36] [Driver][Qualcomm 1065][AT_COMMAND]retrieve message Wayne Lin
2010-07-26 8:30 ` [RFC 24/36] [Driver][Qualcomm 1070][CLOCK] Modify the AXI clock for 1.2Ghz Wayne Lin
2010-07-26 8:30 ` [RFC 25/36] [Driver][Qualcomm 1070][EC_BRG] Adding new EC bridge driver Wayne Lin
2010-07-26 8:30 ` [RFC 26/36] [Driver][Qualcomm 1070][EC_BL] New EC backlight driver porting Wayne Lin
2010-07-26 8:30 ` [RFC 27/36] [Driver][Qualcomm 1070][EC_BRG] Enable NuvoTon WPCE775X driver and disable WinBond WPCE775X driver Wayne Lin
2010-07-26 8:30 ` [RFC 28/36] [Driver][Qualcomm 1070][EC_BL] Enable QCI backlight driver Wayne Lin
2010-07-26 8:30 ` [RFC 29/36] [Driver][Qualcomm 1070][EC_BRG] Correct new EC bridge driver Makefile and Kconfig Wayne Lin
2010-07-26 8:30 ` [RFC 30/36] [Driver][Qualcomm 1070][EC_G_SENSOR] Enable EC gravitation sensor Wayne Lin
2010-07-26 8:30 ` [RFC 31/36] [Driver][Qualcomm 1070][VERSION] 0.1.1 Wayne Lin
2010-07-26 8:30 ` [RFC 32/36] [Driver][Qualcomm 1070][MMC] Enable MMC1 HW detection Wayne Lin
2010-07-26 8:30 ` [RFC 33/36] [Driver][Qualcomm 1070][VERSION] 0.1.2 Wayne Lin
2010-07-26 8:30 ` [RFC 34/36] [Driver][Qualcomm 1070][EC_BAT] Adding newer version battery driver Wayne Lin
2010-07-26 8:30 ` [RFC 35/36] [Driver][Qualcomm 1070][EC_BAT] Enable EC battery Wayne Lin
2010-07-26 8:30 ` [RFC 36/36] [Driver][Qualcomm 1070][VERSION] 0.2.0 Wayne Lin
2010-07-26 8:40 ` Premi, Sanjeev
2010-07-26 8:47 ` Premi, Sanjeev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1280133045-25945-8-git-send-email-wayne.lin@quantatw.com \
--to=00601wayne@gmail.com \
--cc=linux-input@vger.kernel.org \
--cc=wayne.lin@quantatw.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.