summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNitin Garg <nitin.garg@freescale.com>2012-02-05 11:01:55 -0600
committerNitin Garg <nitin.garg@freescale.com>2012-02-05 11:01:55 -0600
commit1af7a6f27a945a38ebbd9dee7f0d733eb5242adc (patch)
treec5b7cc7af3e758dcab0a9c03190d4b6536a52d4e
parent1edd3fa4317853c8005c59a3658da9efe67e06d9 (diff)
ENGR00171216: Add suspend/resume, battery, accelerometer support.
Add suspend/resume, battery, accelerometer support and fix some compilation warnings. Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
-rw-r--r--drivers/hwmon/da9052-adc.c11
-rw-r--r--drivers/hwmon/mxc_mma8451.c236
-rw-r--r--drivers/input/misc/da9052_onkey.c46
-rw-r--r--drivers/mfd/da9052-core.c78
-rw-r--r--drivers/mfd/da9052-i2c.c31
-rw-r--r--drivers/power/Kconfig7
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/max17085_battery.c393
-rw-r--r--drivers/regulator/da9052-regulator.c14
-rw-r--r--drivers/tty/serial/imx.c3
-rw-r--r--include/linux/mfd/da9052/da9052.h28
-rw-r--r--include/linux/mfd/da9052/pm.h4
-rw-r--r--include/linux/mfd/da9052/reg.h6
13 files changed, 699 insertions, 159 deletions
diff --git a/drivers/hwmon/da9052-adc.c b/drivers/hwmon/da9052-adc.c
index 6803fc2ccea3..0c3f64187da8 100644
--- a/drivers/hwmon/da9052-adc.c
+++ b/drivers/hwmon/da9052-adc.c
@@ -2,6 +2,7 @@
* da9052-adc.c -- ADC Driver for Dialog DA9052
*
* Copyright(c) 2009 Dialog Semiconductor Ltd.
+ * Copyright 2010-2012 Freescale Semiconductor, Inc.
*
* Author: Dialog Semiconductor Ltd <dchen@diasemi.com>
*
@@ -39,6 +40,15 @@ static const char *input_names[] = {
[DA9052_ADC_VBBAT] = "BACK-UP BATTERY TEMP",
};
+struct da9052 *da9052_local;
+
+int da9052_adc_read(unsigned char channel)
+{
+ if (da9052_local != NULL)
+ return da9052_manual_read(da9052_local, channel);
+ return -1;
+}
+EXPORT_SYMBOL(da9052_adc_read);
int da9052_manual_read(struct da9052 *da9052,
unsigned char channel)
@@ -591,6 +601,7 @@ static int __init da9052_adc_probe(struct platform_device *pdev)
/* Initialize mutex required for ADC Manual read */
mutex_init(&priv->da9052->manconv_lock);
+ da9052_local = priv->da9052;
return 0;
out_err_create2:
diff --git a/drivers/hwmon/mxc_mma8451.c b/drivers/hwmon/mxc_mma8451.c
index 44817614b7a5..e61e5b4fd22a 100644
--- a/drivers/hwmon/mxc_mma8451.c
+++ b/drivers/hwmon/mxc_mma8451.c
@@ -2,7 +2,7 @@
* mma8451.c - Linux kernel modules for 3-Axis Orientation/Motion
* Detection Sensor
*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
+#include <linux/pm.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -32,24 +33,28 @@
#include <linux/hwmon.h>
#include <linux/input-polldev.h>
-/*
- * Defines
- */
-#define assert(expr)\
- if (!(expr)) {\
- printk(KERN_ERR "Assertion failed! %s,%d,%s,%s\n",\
- __FILE__, __LINE__, __func__, #expr);\
- }
-
#define MMA8451_DRV_NAME "mma8451"
#define MMA8451_I2C_ADDR 0x1C
#define MMA8451_ID 0x1A
+#define POLL_INTERVAL_MIN 10
#define POLL_INTERVAL_MAX 500
#define POLL_INTERVAL 100
#define INPUT_FUZZ 32
#define INPUT_FLAT 32
-#define MODE_CHANGE_DELAY_MS 100
+#define MODE_CHANGE_DELAY_MS 10
+
+#define MMA8451_STATUS_ZYXDR 0x08
+#define MMA8451_BUF_SIZE 6
+
+#define DR_1_25MS 0
+#define DR_2_5MS 1
+#define DR_5_0MS 2
+#define DR_10_0MS 3
+#define DR_20_0MS 4
+#define DR_80_0MS 5
+#define DR_160_0MS 6
+#define DR_640_0MS 7
/* register enum for mma8451 registers */
enum {
@@ -108,6 +113,10 @@ enum {
MMA8451_REG_END,
};
+/* The sensitivity is represented in counts/g. In 2g mode the
+sensitivity is 1024 counts/g. In 4g mode the sensitivity is 512
+counts/g and in 8g mode the sensitivity is 256 counts/g.
+ */
enum {
MODE_2G = 0,
MODE_4G,
@@ -118,68 +127,70 @@ enum {
struct mma8451_status {
u8 mode;
u8 ctl_reg1;
+ bool stop_poll;
};
-static struct mma8451_status mma_status = {
- .mode = 0,
- .ctl_reg1 = 0
-};
-
+static struct mma8451_status mma_status;
static struct input_polled_dev *mma8451_idev;
static struct device *hwmon_dev;
static struct i2c_client *mma8451_i2c_client;
-/***************************************************************
- *
- * Initialization function
- *
- **************************************************************/
-static int mma8451_init_client(struct i2c_client *client)
+static int senstive_mode = MODE_2G;
+static DEFINE_MUTEX(mma8451_lock);
+
+static int mma8451_change_mode(struct i2c_client *client, int mode)
{
int result;
+ /* Put sensor into Standby Mode by clearing the Active bit */
mma_status.ctl_reg1 = 0x00;
- result =
- i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
+ result = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
mma_status.ctl_reg1);
- assert(result == 0);
+ if (result < 0)
+ goto out;
- mma_status.mode = MODE_2G;
- result =
- i2c_smbus_write_byte_data(client, MMA8451_XYZ_DATA_CFG,
+ /* Write the 2g dynamic range value */
+ mma_status.mode = mode;
+ result = i2c_smbus_write_byte_data(client, MMA8451_XYZ_DATA_CFG,
mma_status.mode);
- assert(result == 0);
+ if (result < 0)
+ goto out;
- mma_status.ctl_reg1 |= 0x01;
- result =
- i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
+ /* Set the Active bit and Data rate in CTRL Reg 1 */
+ mma_status.ctl_reg1 |= 0x1;
+ mma_status.ctl_reg1 |= (DR_80_0MS<<3);
+ result = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
mma_status.ctl_reg1);
- assert(result == 0);
+ if (result < 0)
+ goto out;
mdelay(MODE_CHANGE_DELAY_MS);
+ return 0;
+out:
+ dev_err(&client->dev, "error when init mma8451:(%d)", result);
return result;
}
-/***************************************************************
-*
-* read sensor data from mma8451
-*
-***************************************************************/
static int mma8451_read_data(short *x, short *y, short *z)
{
- u8 tmp_data[7];
+ u8 tmp_data[MMA8451_BUF_SIZE];
+ int ret;
- if (i2c_smbus_read_i2c_block_data
- (mma8451_i2c_client, MMA8451_OUT_X_MSB, 7, tmp_data) < 7) {
+ /* Read 14-bit XYZ results using 6 byte */
+ ret = i2c_smbus_read_i2c_block_data(mma8451_i2c_client,
+ MMA8451_OUT_X_MSB, MMA8451_BUF_SIZE, tmp_data);
+ if (ret < MMA8451_BUF_SIZE) {
dev_err(&mma8451_i2c_client->dev, "i2c block read failed\n");
- return -3;
+ return -EIO;
}
+ /* Concatenate the MSB and LSB */
*x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
*y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
*z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
+ /* Drop the lower 2 bits as its 14-bit sample */
*x = (short)(*x) >> 2;
*y = (short)(*y) >> 2;
*z = (short)(*z) >> 2;
@@ -202,24 +213,34 @@ static void report_abs(void)
short x, y, z;
int result;
- do {
- result =
- i2c_smbus_read_byte_data(mma8451_i2c_client,
- MMA8451_STATUS);
- } while (!(result & 0x08)); /* wait for new data */
+ mutex_lock(&mma8451_lock);
+ /* Read Status register */
+ result = i2c_smbus_read_byte_data(mma8451_i2c_client, MMA8451_STATUS);
+
+ /* Check ZYXDR status bit for data available */
+ if (!(result & MMA8451_STATUS_ZYXDR)) {
+ /* Data not ready */
+ goto out;
+ }
+
+ /* Read XYZ data */
if (mma8451_read_data(&x, &y, &z) != 0)
- return;
+ goto out;
+ /* Report XYZ data */
input_report_abs(mma8451_idev->input, ABS_X, x);
input_report_abs(mma8451_idev->input, ABS_Y, y);
input_report_abs(mma8451_idev->input, ABS_Z, z);
input_sync(mma8451_idev->input);
+out:
+ mutex_unlock(&mma8451_lock);
}
static void mma8451_dev_poll(struct input_polled_dev *dev)
{
- report_abs();
+ if (!mma_status.stop_poll)
+ report_abs();
}
static int __devinit mma8451_probe(struct i2c_client *client,
@@ -230,42 +251,50 @@ static int __devinit mma8451_probe(struct i2c_client *client,
struct i2c_adapter *adapter;
mma8451_i2c_client = client;
+ mma_status.stop_poll = false;
+
adapter = to_i2c_adapter(client->dev.parent);
result = i2c_check_functionality(adapter,
I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA);
- assert(result);
+ if (!result)
+ goto err_out;
- printk(KERN_INFO "check mma8451 chip ID\n");
result = i2c_smbus_read_byte_data(client, MMA8451_WHO_AM_I);
- if (MMA8451_ID != result) {
+ if (result != MMA8451_ID) {
dev_err(&client->dev,
"read chip ID 0x%x is not equal to 0x%x!\n", result,
MMA8451_ID);
- printk(KERN_INFO "read chip ID failed\n");
result = -EINVAL;
- goto err_detach_client;
+ goto err_out;
}
/* Initialize the MMA8451 chip */
- result = mma8451_init_client(client);
- assert(result == 0);
+ result = mma8451_change_mode(client, senstive_mode);
+ if (result) {
+ dev_err(&client->dev,
+ "error when init mma8451 chip:(%d)\n", result);
+ goto err_out;
+ }
hwmon_dev = hwmon_device_register(&client->dev);
- assert(!(IS_ERR(hwmon_dev)));
-
- dev_info(&client->dev, "build time %s %s\n", __DATE__, __TIME__);
+ if (!hwmon_dev) {
+ result = -ENOMEM;
+ dev_err(&client->dev,
+ "error when register hwmon device\n");
+ goto err_out;
+ }
- /*input poll device register */
mma8451_idev = input_allocate_polled_device();
if (!mma8451_idev) {
- dev_err(&client->dev, "alloc poll device failed!\n");
result = -ENOMEM;
- return result;
+ dev_err(&client->dev, "alloc poll device failed!\n");
+ goto err_alloc_poll_device;
}
mma8451_idev->poll = mma8451_dev_poll;
mma8451_idev->poll_interval = POLL_INTERVAL;
+ mma8451_idev->poll_interval_min = POLL_INTERVAL_MIN;
mma8451_idev->poll_interval_max = POLL_INTERVAL_MAX;
idev = mma8451_idev->input;
idev->name = MMA8451_DRV_NAME;
@@ -275,70 +304,86 @@ static int __devinit mma8451_probe(struct i2c_client *client,
input_set_abs_params(idev, ABS_X, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
input_set_abs_params(idev, ABS_Y, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
input_set_abs_params(idev, ABS_Z, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
+
result = input_register_polled_device(mma8451_idev);
if (result) {
dev_err(&client->dev, "register poll device failed!\n");
- return result;
+ goto err_register_polled_device;
}
- return result;
-err_detach_client:
+ return 0;
+err_register_polled_device:
+ input_free_polled_device(mma8451_idev);
+err_alloc_poll_device:
+ hwmon_device_unregister(&client->dev);
+err_out:
return result;
}
-static int __devexit mma8451_remove(struct i2c_client *client)
+static int mma8451_stop_chip(struct i2c_client *client)
{
- int result;
- mma_status.ctl_reg1 =
- i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
- result =
- i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
- mma_status.ctl_reg1 & 0xFE);
- assert(result == 0);
+ mma_status.ctl_reg1 = i2c_smbus_read_byte_data(client,
+ MMA8451_CTRL_REG1);
+ return i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
+ mma_status.ctl_reg1 & 0xFE);
+}
+static int __devexit mma8451_remove(struct i2c_client *client)
+{
+ int ret;
+ ret = mma8451_stop_chip(client);
hwmon_device_unregister(hwmon_dev);
- return result;
+ return ret;
}
-static int mma8451_suspend(struct i2c_client *client, pm_message_t mesg)
+void mma8451_shutdown(struct i2c_client *client)
{
- int result;
- mma_status.ctl_reg1 =
- i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
- result =
- i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
- mma_status.ctl_reg1 & 0xFE);
- assert(result == 0);
- return result;
+ int ret;
+
+ /* first, stop polling since this chip will pull sda low if
+ * reboot during poweroff/reboot, add stop function here to
+ * prevent this
+ */
+ mma_status.stop_poll = true;
+
+ ret = mma8451_stop_chip(client);
+ if (ret < 0)
+ dev_err(&client->dev, "stop chip failed:%d\n", ret);
}
-static int mma8451_resume(struct i2c_client *client)
+#ifdef CONFIG_PM_SLEEP
+static int mma8451_suspend(struct device *dev)
{
- int result;
- result =
- i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
- mma_status.ctl_reg1);
- assert(result == 0);
- return result;
+ struct i2c_client *client = to_i2c_client(dev);
+
+ return mma8451_stop_chip(client);
}
+static int mma8451_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ return i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
+ mma_status.ctl_reg1);
+}
+#endif
+
static const struct i2c_device_id mma8451_id[] = {
{MMA8451_DRV_NAME, 0},
- {},
};
-
MODULE_DEVICE_TABLE(i2c, mma8451_id);
+static SIMPLE_DEV_PM_OPS(mma8451_pm_ops, mma8451_suspend, mma8451_resume);
static struct i2c_driver mma8451_driver = {
.driver = {
.name = MMA8451_DRV_NAME,
.owner = THIS_MODULE,
+ .pm = &mma8451_pm_ops,
},
- .suspend = mma8451_suspend,
- .resume = mma8451_resume,
.probe = mma8451_probe,
.remove = __devexit_p(mma8451_remove),
+ .shutdown = mma8451_shutdown,
.id_table = mma8451_id,
};
@@ -352,14 +397,11 @@ static int __init mma8451_init(void)
printk(KERN_INFO "add mma8451 i2c driver failed\n");
return -ENODEV;
}
- printk(KERN_INFO "add mma8451 i2c driver\n");
-
return res;
}
static void __exit mma8451_exit(void)
{
- printk(KERN_INFO "remove mma8451 i2c driver.\n");
i2c_del_driver(&mma8451_driver);
}
diff --git a/drivers/input/misc/da9052_onkey.c b/drivers/input/misc/da9052_onkey.c
index 2271b59261fa..5d223b62e973 100644
--- a/drivers/input/misc/da9052_onkey.c
+++ b/drivers/input/misc/da9052_onkey.c
@@ -1,3 +1,15 @@
+/*
+ * Copyright(c) 2009 Dialog Semiconductor Ltd.
+ * Copyright 2010-2012 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * da9052_onkey.c: Onkey driver for DA9052
+ */
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
@@ -14,6 +26,9 @@ struct da9052_onkey_data {
struct input_dev *input;
};
+/* Flag to enable key events during suspend */
+static bool enable_onkey_events;
+
static void da9052_onkey_report_event(struct da9052_eh_nb *eh_data,
unsigned int event)
{
@@ -33,9 +48,12 @@ static void da9052_onkey_report_event(struct da9052_eh_nb *eh_data,
da9052_unlock(da9052_onkey->da9052);
msg.data = msg.data & DA9052_EVENTB_ENONKEY;
- input_report_key(da9052_onkey->input, KEY_POWER, msg.data);
- input_sync(da9052_onkey->input);
- printk(KERN_INFO "DA9052 ONKEY EVENT REPORTED \n");
+ /* We need onkey events only in suspend mode */
+ if (enable_onkey_events) {
+ input_report_key(da9052_onkey->input, KEY_POWER, msg.data);
+ input_sync(da9052_onkey->input);
+ }
+ pr_debug("DA9052 ONKEY EVENT REPORTED\n");
}
static int __devinit da9052_onkey_probe(struct platform_device *pdev)
@@ -105,12 +123,34 @@ static int __devexit da9052_onkey_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int da9052_onkey_suspend(struct device *dev)
+{
+ enable_onkey_events = true;
+ return 0;
+}
+
+static int da9052_onkey_resume(struct device *dev)
+{
+ enable_onkey_events = false;
+ return 0;
+}
+
+static const struct dev_pm_ops da9052_onkey_pm_ops = {
+ .suspend = da9052_onkey_suspend,
+ .resume = da9052_onkey_resume,
+};
+#else
+static const struct dev_pm_ops da9052_onkey_pm_ops = {};
+#endif
+
static struct platform_driver da9052_onkey_driver = {
.probe = da9052_onkey_probe,
.remove = __devexit_p(da9052_onkey_remove),
.driver = {
.name = "da9052-onkey",
.owner = THIS_MODULE,
+ .pm = &da9052_onkey_pm_ops,
}
};
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c
index f363760de95d..44ba8d9b6f66 100644
--- a/drivers/mfd/da9052-core.c
+++ b/drivers/mfd/da9052-core.c
@@ -2,7 +2,7 @@
* da9052-core.c -- Device access for Dialog DA9052
*
* Copyright(c) 2009 Dialog Semiconductor Ltd.
- *
+ * Copyright 2010-2012 Freescale Semiconductor, Inc.
* Author: Dialog Semiconductor Ltd <dchen@diasemi.com>
*
* This program is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@ struct da9052_eh_nb eve_nb_array[EVE_CNT];
static struct da9052_ssc_ops ssc_ops;
struct mutex manconv_lock;
static struct semaphore eve_nb_array_lock;
+static struct da9052 *da9052_data;
void da9052_lock(struct da9052 *da9052)
{
@@ -248,17 +249,16 @@ static int process_events(struct da9052 *da9052, int events_sts)
/* Check if interrupt is received for this event */
if (!((tmp_events_sts >> cnt) & 0x1))
/* Event bit is not set for this event */
- /* Move to next event */
+ /* Move to next priority event */
continue;
if (event == PEN_DOWN_EVE) {
if (list_empty(&(eve_nb_array[event].nb_list)))
continue;
}
-
/* Event bit is set, execute all registered call backs */
if (down_interruptible(&eve_nb_array_lock)){
- printk(KERN_CRIT "Can't acquire eve_nb_array_lock \n");
+ printk(KERN_CRIT "Can't acquire eve_nb_array_lock\n");
return -EIO;
}
@@ -281,14 +281,11 @@ void eh_workqueue_isr(struct work_struct *work)
container_of(work, struct da9052, eh_isr_work);
struct da9052_ssc_msg eve_data[4];
- struct da9052_ssc_msg eve_mask_data[4];
int events_sts, ret;
- u32 mask;
unsigned char cnt = 0;
/* nIRQ is asserted, read event registeres to know what happened */
events_sts = 0;
- mask = 0;
/* Prepare ssc message to read all four event registers */
for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++) {
@@ -296,13 +293,7 @@ void eh_workqueue_isr(struct work_struct *work)
eve_data[cnt].data = 0;
}
- /* Prepare ssc message to read all four event registers */
- for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++) {
- eve_mask_data[cnt].addr = (DA9052_IRQMASKA_REG + cnt);
- eve_mask_data[cnt].data = 0;
- }
-
- /* Now read all event and mask registers */
+ /* Now read all event registers */
da9052_lock(da9052);
ret = da9052_ssc_read_many(da9052,eve_data, DA9052_EVE_REGISTERS);
@@ -312,22 +303,10 @@ void eh_workqueue_isr(struct work_struct *work)
return;
}
- ret = da9052_ssc_read_many(da9052,eve_mask_data, DA9052_EVE_REGISTERS);
- if (ret) {
- enable_irq(da9052->irq);
- da9052_unlock(da9052);
- return;
- }
/* Collect all events */
for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++)
events_sts |= (eve_data[cnt].data << (DA9052_EVE_REGISTER_SIZE
* cnt));
- /* Collect all mask */
- for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++)
- mask |= (eve_mask_data[cnt].data << (DA9052_EVE_REGISTER_SIZE
- * cnt));
- events_sts &= ~mask;
- da9052_unlock(da9052);
/* Check if we really got any event */
if (events_sts == 0) {
@@ -335,6 +314,7 @@ void eh_workqueue_isr(struct work_struct *work)
da9052_unlock(da9052);
return;
}
+ da9052_unlock(da9052);
/* Process all events occurred */
process_events(da9052, events_sts);
@@ -399,6 +379,7 @@ static int add_da9052_devices(struct da9052 *da9052)
};
struct da9052_tsi_platform_data tsi_data = *(pdata->tsi_data);
+ struct da9052_bat_platform_data bat_data = *(pdata->bat_data);
if (pdata && pdata->init) {
ret = pdata->init(da9052);
@@ -448,7 +429,8 @@ static int add_da9052_devices(struct da9052 *da9052)
if (ret)
return ret;
- ret = da9052_add_subdevice(da9052, "da9052-bat");
+ ret = da9052_add_subdevice_pdata(da9052, "da9052-bat",
+ &bat_data, sizeof(bat_data));
if (ret)
return ret;
@@ -492,6 +474,7 @@ int da9052_ssc_init(struct da9052 *da9052)
ssc_ops.read_many = da9052_i2c_read_many;
} else
return -1;
+
/* Assign the EH notifier block register/de-register functions */
da9052->register_event_notifier = eh_register_nb;
da9052->unregister_event_notifier = eh_unregister_nb;
@@ -503,17 +486,35 @@ int da9052_ssc_init(struct da9052 *da9052)
add_da9052_devices(da9052);
INIT_WORK(&da9052->eh_isr_work, eh_workqueue_isr);
+
ssc_msg.addr = DA9052_IRQMASKA_REG;
ssc_msg.data = 0xff;
da9052->write(da9052, &ssc_msg);
ssc_msg.addr = DA9052_IRQMASKC_REG;
ssc_msg.data = 0xff;
da9052->write(da9052, &ssc_msg);
+
+ /* read chip version */
+ ssc_msg.addr = DA9052_CHIPID_REG;
+ da9052->read(da9052, &ssc_msg);
+ pr_info("DA9053 chip ID reg read=0x%x ", ssc_msg.data);
+ if ((ssc_msg.data & DA9052_CHIPID_MRC) == 0x80) {
+ da9052->chip_version = DA9053_VERSION_AA;
+ pr_info("AA version probed\n");
+ } else if ((ssc_msg.data & DA9052_CHIPID_MRC) == 0xa0) {
+ da9052->chip_version = DA9053_VERSION_BB;
+ pr_info("BB version probed\n");
+ } else {
+ da9052->chip_version = 0;
+ pr_info("unknown chip version\n");
+ }
+
if (request_irq(da9052->irq, da9052_eh_isr, IRQ_TYPE_LEVEL_LOW,
DA9052_EH_DEVICE_NAME, da9052))
return -EIO;
enable_irq_wake(da9052->irq);
-
+ da9052_data = da9052;
+
return 0;
}
@@ -529,6 +530,27 @@ void da9052_ssc_exit(struct da9052 *da9052)
return;
}
+void da9053_power_off(void)
+{
+ struct da9052_ssc_msg ssc_msg;
+ struct da9052_ssc_msg ssc_msg_dummy[2];
+ if (!da9052_data)
+ return;
+
+ ssc_msg.addr = DA9052_CONTROLB_REG;
+ da9052_data->read(da9052_data, &ssc_msg);
+ ssc_msg_dummy[0].addr = DA9052_CONTROLB_REG;
+ ssc_msg_dummy[0].data = ssc_msg.data | DA9052_CONTROLB_SHUTDOWN;
+ ssc_msg_dummy[1].addr = DA9052_GPID9_REG;
+ ssc_msg_dummy[1].data = 0;
+ da9052_data->write_many(da9052_data, &ssc_msg_dummy[0], 2);
+}
+
+int da9053_get_chip_version(void)
+{
+ return da9052_data->chip_version;
+}
+
MODULE_AUTHOR("Dialog Semiconductor Ltd <dchen@diasemi.com>");
MODULE_DESCRIPTION("DA9052 MFD Core");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c
index 4f050896d962..214f657866ee 100644
--- a/drivers/mfd/da9052-i2c.c
+++ b/drivers/mfd/da9052-i2c.c
@@ -1,5 +1,6 @@
/*
* Copyright(c) 2009 Dialog Semiconductor Ltd.
+ * Copyright 2010-2012 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,23 +22,21 @@ static struct da9052 *da9052_i2c;
static int da9052_i2c_is_connected(void)
{
+ struct da9052_ssc_msg msg;
+ int retries = 10, ret = -1;
+
+ msg.addr = DA9052_INTERFACE_REG;
+ do {
+ /* Test i2c connectivity by reading the GPIO_0-1 register */
+ if (0 != da9052_i2c_read(da9052_i2c, &msg)) {
+ printk(KERN_INFO"da9052_i2c_is_connected - i2c read failed.....\n");
+ } else {
+ printk(KERN_INFO"da9052_i2c_is_connected - i2c read success....\n");
+ ret = 0;
+ }
+ } while (ret != 0 && retries--);
- struct da9052_ssc_msg msg;
-
- //printk("Entered da9052_i2c_is_connected.............\n");
-
- msg.addr = DA9052_INTERFACE_REG;
-
- /* Test spi connectivity by performing read of the GPIO_0-1 register */
- if ( 0 != da9052_i2c_read(da9052_i2c, &msg)) {
- printk("da9052_i2c_is_connected - i2c read failed.............\n");
- return -1;
- }
- else {
- printk("da9052_i2c_is_connected - i2c read success..............\n");
- return 0;
- }
-
+ return ret;
}
static int __devinit da9052_i2c_probe(struct i2c_client *client,
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 2e700233b8ff..8b7aefc274c6 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -128,6 +128,13 @@ config BATTERY_DA9030
Say Y here to enable support for batteries charger integrated into
DA9030 PMIC.
+config BATTERY_MAX17085
+ tristate "Maxim MAX17085 charger"
+ depends on PMIC_DA9052 && SENSORS_DA9052
+ help
+ Say Y to include support for the battery on the MAX17085. This
+ is dependent on DA9052 sensor.
+
config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 470bc3867245..272ae9e429eb 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -35,3 +35,4 @@ obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
+obj-$(CONFIG_BATTERY_MAX17085) += max17085_battery.o
diff --git a/drivers/power/max17085_battery.c b/drivers/power/max17085_battery.c
new file mode 100644
index 000000000000..60e653031a81
--- /dev/null
+++ b/drivers/power/max17085_battery.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * MAX17085 Battery driver
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <mach/gpio.h>
+
+struct max17085_chip {
+ struct device *dev;
+
+ /*gpio*/
+ int pwr_good;
+ int ac_in;
+ int charge_now;
+ int charge_done;
+
+ struct power_supply ac;
+ struct power_supply bat;
+ struct delayed_work work;
+
+ int online;
+ int health;
+ int status;
+ int voltage_uV;
+ int cap;
+};
+
+#define MAX17085_DELAY 3000
+#define MAX17085_DEF_TEMP 30
+
+static int max17085_bat_get_mfr(struct power_supply *psy,
+ union power_supply_propval *val)
+{
+ val->strval = "unknown";
+ return 0;
+}
+
+static int max17085_bat_get_tech(struct power_supply *psy,
+ union power_supply_propval *val)
+{
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ return 0;
+}
+
+static int max17085_bat_get_cap(struct power_supply *psy,
+ union power_supply_propval *val)
+{
+ struct max17085_chip *chip = container_of(psy,
+ struct max17085_chip, bat);
+
+ val->intval = chip->cap;
+ return 0;
+}
+
+static int max17085_bat_get_volt(struct power_supply *psy,
+ union power_supply_propval *val)
+{
+ struct max17085_chip *chip = container_of(psy,
+ struct max17085_chip, bat);
+
+ val->intval = chip->voltage_uV;
+ return 0;
+}
+
+static int max17085_bat_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ int ret = 0;
+ struct max17085_chip *chip = container_of(psy,
+ struct max17085_chip, bat);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = chip->status;
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ val->intval = chip->health;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ ret = max17085_bat_get_cap(psy, val);
+ if (ret)
+ return ret;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ ret = max17085_bat_get_volt(psy, val);
+ if (ret)
+ return ret;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ ret = max17085_bat_get_mfr(psy, val);
+ if (ret)
+ return ret;
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ ret = max17085_bat_get_tech(psy, val);
+ if (ret)
+ return ret;
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = 1;
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ val->intval = MAX17085_DEF_TEMP;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int max17085_ac_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max17085_chip *chip = container_of(psy,
+ struct max17085_chip, ac);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = chip->online;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void max17085_get_online(struct max17085_chip *chip)
+{
+ int level = gpio_get_value(chip->ac_in);
+ int cur_online = !level;
+
+ if (chip->online != cur_online) {
+ chip->online = cur_online;
+ power_supply_changed(&chip->ac);
+ }
+}
+
+static void max17085_get_health(struct max17085_chip *chip)
+{
+ int level = gpio_get_value(chip->pwr_good);
+
+ if (level && (chip->voltage_uV >= 0))
+ chip->health = POWER_SUPPLY_HEALTH_GOOD;
+ else
+ chip->health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+}
+
+extern int da9052_adc_read(unsigned char channel);
+#define VOLT_REG_TO_MV(val) ((val * 2500) / 1024)
+#define BATT_TO_ADC_SCALE 11
+static void max17085_get_volt(struct max17085_chip *chip)
+{
+ int val;
+ val = da9052_adc_read(6);
+ if (val > 0)
+ chip->voltage_uV = VOLT_REG_TO_MV(val)*1000*BATT_TO_ADC_SCALE;
+ else
+ chip->voltage_uV = -1;
+}
+
+#define BATT_EMPTY_MV 9955
+#define BATT_FULL_MV 11500
+static void max17085_get_cap(struct max17085_chip *chip)
+{
+ int old_cap = chip->cap;
+
+ if (chip->voltage_uV > BATT_EMPTY_MV*1000) {
+ chip->cap = (chip->voltage_uV/1000 - BATT_EMPTY_MV) * 100/
+ (BATT_FULL_MV - BATT_EMPTY_MV);
+ if (chip->cap > 100)
+ chip->cap = 100;
+ } else
+ chip->cap = 0;
+
+ if (chip->cap != old_cap)
+ power_supply_changed(&chip->bat);
+}
+
+static void max17085_update_status(struct max17085_chip *chip)
+{
+ int old_status = chip->status;
+
+ if (chip->online) {
+ if (chip->voltage_uV/1000 < BATT_FULL_MV)
+ chip->status =
+ POWER_SUPPLY_STATUS_CHARGING;
+ else
+ chip->status =
+ POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else
+ chip->status = POWER_SUPPLY_STATUS_DISCHARGING;
+
+ if (chip->voltage_uV/1000 >= BATT_FULL_MV)
+ chip->status = POWER_SUPPLY_STATUS_FULL;
+
+ if (old_status != POWER_SUPPLY_STATUS_UNKNOWN &&
+ old_status != chip->status)
+ power_supply_changed(&chip->bat);
+
+ if (chip->cap < 20) {
+ gpio_set_value(chip->charge_now, 1);
+ gpio_set_value(chip->charge_done, 0);
+ } else if (chip->cap < 80) {
+ gpio_set_value(chip->charge_now, 1);
+ gpio_set_value(chip->charge_done, 1);
+ } else {
+ gpio_set_value(chip->charge_now, 0);
+ gpio_set_value(chip->charge_done, 1);
+ }
+}
+
+static void max17085_work(struct work_struct *work)
+{
+ struct max17085_chip *chip = container_of(work,
+ struct max17085_chip, work.work);
+
+ max17085_get_online(chip);
+ max17085_get_volt(chip);
+ max17085_get_health(chip);
+ max17085_get_cap(chip);
+ max17085_update_status(chip);
+
+ schedule_delayed_work(&chip->work, msecs_to_jiffies(MAX17085_DELAY));
+}
+
+static enum power_supply_property max17085_bat_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property max17085_ac_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static int max17085_bat_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct max17085_chip *chip;
+ struct resource *res;
+
+ chip = kzalloc(sizeof(struct max17085_chip), GFP_KERNEL);
+ if (!chip) {
+ ret = -ENOMEM;
+ goto chip_alloc_failed;
+ }
+
+ res = platform_get_resource_byname(pdev,
+ IORESOURCE_IO, "pwr-good");
+ if (res == NULL) {
+ ret = -EINVAL;
+ goto resource_failed;
+ }
+ chip->pwr_good = res->start;
+ res = platform_get_resource_byname(pdev,
+ IORESOURCE_IO, "ac-in");
+ if (res == NULL) {
+ ret = -EINVAL;
+ goto resource_failed;
+ }
+ chip->ac_in = res->start;
+ res = platform_get_resource_byname(pdev,
+ IORESOURCE_IO, "charge-now");
+ if (res == NULL) {
+ ret = -EINVAL;
+ goto resource_failed;
+ }
+ chip->charge_now = res->start;
+ res = platform_get_resource_byname(pdev,
+ IORESOURCE_IO, "charge-done");
+ if (res == NULL) {
+ ret = -EINVAL;
+ goto resource_failed;
+ }
+ chip->charge_done = res->start;
+
+ chip->dev = &pdev->dev;
+ chip->bat.name = "battery";
+ chip->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+ chip->bat.properties = max17085_bat_props;
+ chip->bat.num_properties = ARRAY_SIZE(max17085_bat_props);
+ chip->bat.get_property = max17085_bat_get_property;
+ chip->bat.use_for_apm = 1;
+
+ chip->ac.name = "ac";
+ chip->ac.type = POWER_SUPPLY_TYPE_MAINS;
+ chip->ac.properties = max17085_ac_props;
+ chip->ac.num_properties = ARRAY_SIZE(max17085_ac_props);
+ chip->ac.get_property = max17085_ac_get_property;
+
+ platform_set_drvdata(pdev, chip);
+
+ ret = power_supply_register(&pdev->dev, &chip->ac);
+ if (ret) {
+ dev_err(chip->dev, "failed to register ac\n");
+ goto register_ac_failed;
+ }
+
+ ret = power_supply_register(&pdev->dev, &chip->bat);
+ if (ret) {
+ dev_err(chip->dev, "failed to register battery\n");
+ goto register_batt_failed;
+ }
+
+ max17085_get_online(chip);
+
+ INIT_DELAYED_WORK_DEFERRABLE(&chip->work, max17085_work);
+ schedule_delayed_work(&chip->work, msecs_to_jiffies(MAX17085_DELAY));
+
+ return ret;
+
+register_batt_failed:
+ power_supply_unregister(&chip->ac);
+register_ac_failed:
+resource_failed:
+ kfree(chip);
+chip_alloc_failed:
+ return ret;
+}
+
+static int max17085_bat_remove(struct platform_device *pdev)
+{
+ struct max17085_chip *chip = platform_get_drvdata(pdev);
+
+ cancel_delayed_work(&chip->work);
+ power_supply_unregister(&chip->bat);
+ power_supply_unregister(&chip->ac);
+ kfree(chip);
+
+ return 0;
+}
+
+static void max17085_bat_shutdown(struct platform_device *pdev)
+{
+ struct max17085_chip *chip = platform_get_drvdata(pdev);
+
+ cancel_delayed_work_sync(&chip->work);
+}
+
+static struct platform_driver max17085_bat_driver = {
+ .driver = {
+ .name = "max17085_bat",
+ },
+ .probe = max17085_bat_probe,
+ .remove = max17085_bat_remove,
+ .shutdown = max17085_bat_shutdown,
+
+};
+
+static int __devinit max17085_bat_init(void)
+{
+ return platform_driver_register(&max17085_bat_driver);
+}
+
+static void __devexit max17085_bat_exit(void)
+{
+ platform_driver_unregister(&max17085_bat_driver);
+}
+
+module_init(max17085_bat_init);
+module_exit(max17085_bat_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MAX17085 battery driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c
index 09882ddd8d92..0ec4666f977d 100644
--- a/drivers/regulator/da9052-regulator.c
+++ b/drivers/regulator/da9052-regulator.c
@@ -142,12 +142,12 @@ struct regulator_info da9052_regulators[] = {
DA9052_BUCK_MEM_VOLT_LOWER,
DA9052_BUCK_MEM_STEP, DA9052_BUCKMEM_REG,
DA9052_BUCKMEM_VBMEM, DA9052_BUCKMEM_BMEMEN),
-#if defined (CONFIG_PMIC_DA9052)
+#if defined(CONFIG_PMIC_DA9052)
DA9052_LDO(DA9052_BUCK_PERI, DA9052_BUCK_PERI_VOLT_UPPER,
DA9052_BUCK_PERI_VOLT_LOWER,
DA9052_BUCK_PERI_STEP_BELOW_3000, DA9052_BUCKPERI_REG,
DA9052_BUCKPERI_VBPERI, DA9052_BUCKPERI_BPERIEN),
-#elif defined (CONFIG_PMIC_DA9053AA) || (CONFIG_PMIC_DA9053Bx)
+#elif defined(CONFIG_PMIC_DA9053AA) || defined(CONFIG_PMIC_DA9053Bx)
DA9052_LDO(DA9052_BUCK_PERI, DA9052_BUCK_PERI_VOLT_UPPER,
DA9052_BUCK_PERI_VOLT_LOWER,
DA9052_BUCK_PERI_STEP, DA9052_BUCKPERI_REG,
@@ -247,7 +247,7 @@ int da9052_ldo_buck_set_voltage(struct regulator_dev *rdev,
int id = rdev_get_id(rdev);
int ret;
int ldo_volt = 0;
- selector;
+ (void)selector;
/* Below if condition is there for added setvoltage attribute
in sysfs */
@@ -265,7 +265,7 @@ int da9052_ldo_buck_set_voltage(struct regulator_dev *rdev,
if (max_uV < da9052_regulators[id].reg_const.min_uV ||
max_uV > da9052_regulators[id].reg_const.max_uV)
return -EINVAL;
-#if defined (CONFIG_PMIC_DA9052)
+#if defined(CONFIG_PMIC_DA9052)
/* Get the ldo register value */
/* Varying step size for BUCK PERI */
if ((da9052_regulators[id].reg_desc.id == DA9052_BUCK_PERI) &&
@@ -283,7 +283,7 @@ int da9052_ldo_buck_set_voltage(struct regulator_dev *rdev,
da9052_regulators[id].reg_const.min_uV > max_uV)
return -EINVAL;
}
-#elif defined (CONFIG_PMIC_DA9053AA) ||(CONFIG_PMIC_DA9053Bx)
+#elif defined(CONFIG_PMIC_DA9053AA) || defined(CONFIG_PMIC_DA9053Bx)
ldo_volt = (min_uV - da9052_regulators[id].reg_const.min_uV)/
(da9052_regulators[id].step_uV);
/* Check for maximum value */
@@ -378,7 +378,7 @@ int da9052_ldo_buck_get_voltage(struct regulator_dev *rdev)
da9052_unlock(priv->da9052);
ldo_volt = ssc_msg.data & da9052_regulators[id].mask_bits;
-#if defined (CONFIG_PMIC_DA9052)
+#if defined(CONFIG_PMIC_DA9052)
if (da9052_regulators[id].reg_desc.id == DA9052_BUCK_PERI) {
if (ldo_volt >= DA9052_BUCK_PERI_VALUES_UPTO_3000) {
ldo_volt_uV = ((DA9052_BUCK_PERI_VALUES_UPTO_3000 *
@@ -396,7 +396,7 @@ int da9052_ldo_buck_get_voltage(struct regulator_dev *rdev)
ldo_volt_uV = (ldo_volt * da9052_regulators[id].step_uV) +
da9052_regulators[id].reg_const.min_uV;
}
-#elif defined (CONFIG_PMIC_DA9053AA) || (CONFIG_PMIC_DA9053Bx)
+#elif defined(CONFIG_PMIC_DA9053AA) || defined(CONFIG_PMIC_DA9053Bx)
ldo_volt_uV = (ldo_volt * da9052_regulators[id].step_uV) +
da9052_regulators[id].reg_const.min_uV;
#endif
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 094ce699f9eb..004ee124819d 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2,6 +2,7 @@
* linux/drivers/serial/imx.c
*
* Driver for Motorola IMX serial ports
+ * Copyright 2010-2012 Freescale Semiconductor, Inc.
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
*
@@ -257,7 +258,7 @@ static void imx_timeout(unsigned long data)
struct imx_port *sport = (struct imx_port *)data;
unsigned long flags;
- if (sport->port.state) {
+ if ((&sport->port) && (sport->port.state)) {
spin_lock_irqsave(&sport->port.lock, flags);
imx_mctrl_check(sport);
spin_unlock_irqrestore(&sport->port.lock, flags);
diff --git a/include/linux/mfd/da9052/da9052.h b/include/linux/mfd/da9052/da9052.h
index fd83f73bcd82..18dd74bde4f8 100644
--- a/include/linux/mfd/da9052/da9052.h
+++ b/include/linux/mfd/da9052/da9052.h
@@ -75,6 +75,9 @@
#define DA9052_SSC_I2C_REPEAT_WRITE_MODE 1
#define DA9052_SSC_I2C_WRITE_MODE DA9052_SSC_I2C_REPEAT_WRITE_MODE
+#define DA9053_VERSION_AA 1
+#define DA9053_VERSION_BB 2
+
struct da9052_ssc_msg {
unsigned char data;
unsigned char addr;
@@ -95,7 +98,6 @@ struct da9052_eh_nb{
struct da9052_regulator_init_data {
struct regulator_init_data *init_data;
int id;
-
};
struct da9052_regulator_platform_data {
@@ -114,6 +116,25 @@ struct da9052_tsi_platform_data {
};
+struct da9052_bat_platform_data {
+ u16 sw_temp_control_en;
+ u16 monitoring_interval;
+ u16 sw_bat_temp_threshold;
+ u16 sw_junc_temp_threshold;
+ u16 hysteresis_window_size;
+ u16 current_monitoring_window;
+ u16 bat_with_no_resistor;
+ u16 bat_capacity_limit_low;
+ u16 bat_capacity_full;
+ u16 bat_capacity_limit_high;
+ u16 chg_hysteresis_const;
+ u16 hysteresis_reading_interval;
+ u16 hysteresis_no_of_reading;
+ u16 filter_size;
+ u16 bat_volt_cutoff;
+ u16 vbat_first_valid_detect_iteration;
+};
+
struct da9052 {
struct mutex ssc_lock;
struct mutex eve_nb_lock;
@@ -143,9 +164,9 @@ struct da9052 {
struct device *dev;
struct i2c_adapter *adapter;
unsigned char slave_addr;
+ int chip_version;
};
-
struct da9052_platform_data {
int (*init)(struct da9052 *da9052);
int irq_high;
@@ -156,6 +177,7 @@ struct da9052_platform_data {
struct regulator_init_data *regulators;
struct da9052_leds_platform_data *led_data;
struct da9052_tsi_platform_data *tsi_data;
+ struct da9052_bat_platform_data *bat_data;
};
struct da9052_ssc_ops {
@@ -206,4 +228,6 @@ int eh_register_nb(struct da9052 *da9052, struct da9052_eh_nb *nb);
int eh_unregister_nb(struct da9052 *da9052, struct da9052_eh_nb *nb);
int da9052_manual_read(struct da9052 *da9052,
unsigned char channel);
+void da9053_power_off(void);
+int da9053_get_chip_version(void);
#endif /* __LINUX_MFD_DA9052_DA9052_H */
diff --git a/include/linux/mfd/da9052/pm.h b/include/linux/mfd/da9052/pm.h
index 9a1c4f8b4ea8..f5901e8f1ed1 100644
--- a/include/linux/mfd/da9052/pm.h
+++ b/include/linux/mfd/da9052/pm.h
@@ -50,14 +50,14 @@
#define DA9052_BUCK_MEM_VOLT_UPPER 2500
#define DA9052_BUCK_MEM_VOLT_LOWER 925
#define DA9052_BUCK_MEM_STEP 25
-#if defined (CONFIG_PMIC_DA9052)
+#if defined(CONFIG_PMIC_DA9052)
#define DA9052_BUCK_PERI_VOLT_UPPER 3600
#define DA9052_BUCK_PERI_VOLT_LOWER 1800
#define DA9052_BUCK_PERI_STEP_BELOW_3000 50
#define DA9052_BUCK_PERI_STEP_ABOVE_3000 100000
#define DA9052_BUCK_PERI_VALUES_UPTO_3000 24
#define DA9052_BUCK_PERI_VALUES_3000 3000000
-#elif defined (CONFIG_PMIC_DA9053AA) || (CONFIG_PMIC_DA9053Bx)
+#elif defined(CONFIG_PMIC_DA9053AA) || defined(CONFIG_PMIC_DA9053Bx)
#define DA9052_BUCK_PERI_VOLT_UPPER 2500
#define DA9052_BUCK_PERI_VOLT_LOWER 925
#define DA9052_BUCK_PERI_STEP 25
diff --git a/include/linux/mfd/da9052/reg.h b/include/linux/mfd/da9052/reg.h
index 9daaa02e565f..8c4c9dff8fe5 100644
--- a/include/linux/mfd/da9052/reg.h
+++ b/include/linux/mfd/da9052/reg.h
@@ -533,10 +533,10 @@
/* BUCKPERI REGISTER */
#define DA9052_BUCKPERI_BPERICONF (1<<7)
#define DA9052_BUCKPERI_BPERIEN (1<<6)
-#if defined (CONFIG_PMIC_DA9052)
+#if defined(CONFIG_PMIC_DA9052)
#define DA9052_BUCKPERI_BPERIHS (1<<5)
#define DA9052_BUCKPERI_VBPERI (31<<0)
-#elif defined (CONFIG_PMIC_DA9053AA) || (CONFIG_PMIC_DA9053Bx)
+#elif defined(CONFIG_PMIC_DA9053AA) || defined(CONFIG_PMIC_DA9053Bx)
#define DA9052_BUCKPERI_VBPERI (63<<0)
#endif
@@ -663,7 +663,7 @@
#define DA9052_BOOST_BOOSTEN (1<<0)
/* LED COUNT REGISTER */
-#if defined (CONFIG_PMIC_DA9053Bx)
+#if defined(CONFIG_PMIC_DA9053Bx)
#define DA9052_LEDCONT_SELLEDMODE (1<<7)
#endif
#define DA9052_LEDCONT_LED3ICONT (1<<6)