summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Zhu <r65037@freescale.com>2008-03-12 10:27:26 +0800
committerDaniel Schaeffer <daniel.schaeffer@timesys.com>2008-08-25 15:20:43 -0400
commitaba6a1b9f031fdf426c03c42c2cd1c55df0680d6 (patch)
tree825a32bee3030c7a6f3ef8e183497e89f26a939b
parent12afc0de99f62b780b97d9441fc577cd5fe1582a (diff)
ENGR00068036 3DS pmic adc arbitration fix
Fix 3DS pmic adc arbitration fix and batt hw event support Signed-off-by: Mark Zhou <b02241@freescale.com>
-rw-r--r--drivers/input/touchscreen/mxc_ts.c6
-rw-r--r--drivers/mxc/pmic/Makefile1
-rw-r--r--drivers/mxc/pmic/mc13783/pmic_adc.c58
-rw-r--r--drivers/mxc/pmic/mc13783/pmic_adc_defs.h4
-rw-r--r--drivers/mxc/pmic/mc13783/pmic_battery.c361
-rw-r--r--drivers/mxc/pmic/mc13783/pmic_power.c34
-rw-r--r--include/asm-arm/arch-mxc/pmic_battery.h42
-rw-r--r--include/asm-arm/arch-mxc/pmic_status.h2
8 files changed, 446 insertions, 62 deletions
diff --git a/drivers/input/touchscreen/mxc_ts.c b/drivers/input/touchscreen/mxc_ts.c
index 514f73082bfe..eefd4b9f5068 100644
--- a/drivers/input/touchscreen/mxc_ts.c
+++ b/drivers/input/touchscreen/mxc_ts.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -49,8 +49,8 @@ static int ts_thread(void *arg)
while (input_ts_installed) {
try_to_freeze();
memset(&ts_sample, 0, sizeof(t_touch_screen));
- pmic_adc_get_touch_sample(&ts_sample, !wait);
-
+ if (0 != pmic_adc_get_touch_sample(&ts_sample, !wait))
+ continue;
input_report_abs(mxc_inputdev, ABS_X, ts_sample.x_position);
input_report_abs(mxc_inputdev, ABS_Y, ts_sample.y_position);
input_report_abs(mxc_inputdev, ABS_PRESSURE,
diff --git a/drivers/mxc/pmic/Makefile b/drivers/mxc/pmic/Makefile
index d937cf72d69d..b4312cca7080 100644
--- a/drivers/mxc/pmic/Makefile
+++ b/drivers/mxc/pmic/Makefile
@@ -4,4 +4,3 @@
obj-y += core/
obj-$(CONFIG_MXC_PMIC_MC13783) += mc13783/
-obj-$(CONFIG_MXC_PMIC_SC55112) += sc55112/
diff --git a/drivers/mxc/pmic/mc13783/pmic_adc.c b/drivers/mxc/pmic/mc13783/pmic_adc.c
index e29a1d254b3e..05874249b66e 100644
--- a/drivers/mxc/pmic/mc13783/pmic_adc.c
+++ b/drivers/mxc/pmic/mc13783/pmic_adc.c
@@ -93,6 +93,8 @@ static bool wait_ts;
static bool monitor_en;
static bool monitor_adc;
static t_check_mode wcomp_mode;
+static DECLARE_MUTEX(convert_mutex);
+
void (*monitoring_cb) (void); /*call back to be called when event is detected. */
static DECLARE_WAIT_QUEUE_HEAD(queue_adc_busy);
@@ -159,7 +161,15 @@ static int pmic_adc_suspend(struct platform_device *pdev, pm_message_t state)
static int pmic_adc_resume(struct platform_device *pdev)
{
/* nothing for mc13783 adc */
+ unsigned int adc_0_reg, adc_1_reg;
suspend_flag = 0;
+
+ /* let interrupt of TSI again */
+ adc_0_reg = ADC_WAIT_TSI_0;
+ CHECK_ERROR(pmic_write_reg(REG_ADC_0, adc_0_reg, PMIC_ALL_BITS));
+ adc_1_reg = ADC_WAIT_TSI_1 | (ADC_BIS * adc_ts);
+ CHECK_ERROR(pmic_write_reg(REG_ADC_1, adc_1_reg, PMIC_ALL_BITS));
+
while (swait > 0) {
swait--;
wake_up_interruptible(&suspendq);
@@ -450,6 +460,9 @@ int pmic_adc_init(void)
CHECK_ERROR(pmic_write_reg(REG_ADC_2, reg_value, PMIC_ALL_BITS));
CHECK_ERROR(pmic_write_reg(REG_ADC_3, DEF_ADC_3, PMIC_ALL_BITS));
CHECK_ERROR(pmic_write_reg(REG_ADC_4, reg_value, PMIC_ALL_BITS));
+ reg_value = 0x001000;
+ CHECK_ERROR(pmic_write_reg(REG_ARBITRATION_PERIPHERAL_AUDIO, reg_value,
+ 0xFFFFFF));
data_ready_adc_1 = false;
data_ready_adc_2 = false;
@@ -554,11 +567,13 @@ PMIC_STATUS mc13783_adc_convert(t_adc_param * adc_param)
/* configure adc to wait tsi interrupt */
INIT_COMPLETION(adc_tsi);
pr_debug("mc13783 ADC - pmic_write_reg ....\n");
- adc_0_reg = 0x001c00 | (ADC_BIS * use_bis);
+ /*for ts don't use bis */
+ adc_0_reg = 0x001c00 | (ADC_BIS * 0);
pmic_event_unmask(EVENT_TSI);
CHECK_ERROR(pmic_write_reg
(REG_ADC_0, adc_0_reg, PMIC_ALL_BITS));
- adc_1_reg = 0x200001 | (ADC_BIS * adc_ts);
+ /*for ts don't use bis */
+ adc_1_reg = 0x200001 | (ADC_BIS * 0);
CHECK_ERROR(pmic_write_reg
(REG_ADC_1, adc_1_reg, PMIC_ALL_BITS));
pr_debug("wait tsi ....\n");
@@ -566,7 +581,9 @@ PMIC_STATUS mc13783_adc_convert(t_adc_param * adc_param)
wait_for_completion_interruptible(&adc_tsi);
wait_ts = false;
}
- use_bis = mc13783_adc_request();
+ if (adc_param->read_ts == false)
+ down(&convert_mutex);
+ use_bis = mc13783_adc_request(adc_param->read_ts);
if (use_bis < 0) {
pr_debug("process has received a signal and got interrupted\n");
return -EINTR;
@@ -696,6 +713,9 @@ PMIC_STATUS mc13783_adc_convert(t_adc_param * adc_param)
adc_param->ts_value.contact_resistance = adc_param->value[6];
} */
mc13783_adc_release(use_bis);
+ if (adc_param->read_ts == false)
+ up(&convert_mutex);
+
return PMIC_SUCCESS;
}
@@ -935,9 +955,12 @@ PMIC_STATUS pmic_adc_get_touch_mode(t_touch_mode * touch_mode)
*/
PMIC_STATUS pmic_adc_get_touch_sample(t_touch_screen * touch_sample, int wait)
{
- mc13783_adc_read_ts(touch_sample, wait);
- pmic_adc_filter(touch_sample);
- return PMIC_SUCCESS;
+ if (mc13783_adc_read_ts(touch_sample, wait) != 0)
+ return PMIC_ERROR;
+ if (0 == pmic_adc_filter(touch_sample))
+ return PMIC_SUCCESS;
+ else
+ return PMIC_ERROR;
}
/*!
@@ -962,7 +985,8 @@ PMIC_STATUS mc13783_adc_read_ts(t_touch_screen * ts_value, int wait_tsi)
mc13783_adc_init_param(&param);
param.wait_tsi = wait_tsi;
param.read_ts = true;
- mc13783_adc_convert(&param);
+ if (mc13783_adc_convert(&param) != 0)
+ return PMIC_ERROR;
/* check if x-y is ok */
if ((param.ts_value.x_position1 < TS_X_MAX) &&
(param.ts_value.x_position1 >= TS_X_MIN) &&
@@ -1038,16 +1062,22 @@ PMIC_STATUS pmic_adc_get_battery_current(t_conversion_mode mode,
* @return This function returns index of ADC to be used (0 or 1) if successful.
return -1 if error.
*/
-int mc13783_adc_request(void)
+int mc13783_adc_request(bool read_ts)
{
int adc_index = -1;
- if (((adc_dev[0] == ADC_USED) && (adc_dev[1] == ADC_USED))) {
- /* all ADC is used wait... */
- wait_event(queue_adc_busy, 0);
- } else if (adc_dev[0] == ADC_FREE) {
+ if (read_ts != 0) {
+ /*for ts we use bis=0 */
+ if (adc_dev[0] == ADC_USED)
+ return -1;
+ /*no wait here */
adc_dev[0] = ADC_USED;
adc_index = 0;
- } else if (adc_dev[1] == ADC_FREE) {
+ } else {
+ /*for other adc use bis = 1 */
+ if (adc_dev[1] == ADC_USED) {
+ return -1;
+ /*no wait here */
+ }
adc_dev[1] = ADC_USED;
adc_index = 1;
}
@@ -1143,7 +1173,7 @@ PMIC_STATUS pmic_adc_active_comparator(unsigned char low,
monitoring.channel = channel;
monitoring.callback = (void *)callback;
- use_bis = mc13783_adc_request();
+ use_bis = mc13783_adc_request(false);
if (use_bis < 0) {
pr_debug("mc13783_adc : request error\n");
return PMIC_ERROR;
diff --git a/drivers/mxc/pmic/mc13783/pmic_adc_defs.h b/drivers/mxc/pmic/mc13783/pmic_adc_defs.h
index c2a282c829ca..db1b08232c77 100644
--- a/drivers/mxc/pmic/mc13783/pmic_adc_defs.h
+++ b/drivers/mxc/pmic/mc13783/pmic_adc_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -283,7 +283,7 @@ static int pmic_adc_filter(t_touch_screen * ts_curr);
* @return This function returns index of ADC to be used (0 or 1) if successful.
return -1 if error.
*/
-int mc13783_adc_request(void);
+int mc13783_adc_request(bool read_ts);
/*!
* This function is used to update buffer of touch screen value in read mode.
diff --git a/drivers/mxc/pmic/mc13783/pmic_battery.c b/drivers/mxc/pmic/mc13783/pmic_battery.c
index c8a6da093012..b3d737e13c48 100644
--- a/drivers/mxc/pmic/mc13783/pmic_battery.c
+++ b/drivers/mxc/pmic/mc13783/pmic_battery.c
@@ -34,6 +34,11 @@
#include "pmic_battery_defs.h"
+#include <asm/arch/pmic_power.h>
+#ifdef MXC_HWEVENT
+#include <../drivers/mxc/hw_event/mxc_hw_event.h>
+#endif
+
static int pmic_battery_major;
/*!
@@ -71,6 +76,89 @@ EXPORT_SYMBOL(pmic_batt_set_5k_pull);
EXPORT_SYMBOL(pmic_batt_event_subscribe);
EXPORT_SYMBOL(pmic_batt_event_unsubscribe);
+static DECLARE_MUTEX(count_mutex); /* open count mutex */
+static int open_count; /* open count for device file */
+
+/*!
+ * Callback function for events, we want on MGN board
+ */
+static void callback_chg_detect(void)
+{
+#ifdef MXC_HWEVENT
+ t_sensor_bits sensor;
+ struct mxc_hw_event event = { HWE_BAT_CHARGER_PLUG, 0 };
+
+ pr_debug("In callback_chg_detect\n");
+
+ /* get sensor values */
+ pmic_get_sensors(&sensor);
+
+ pr_debug("Callback, charger detect:%d\n", sensor.sense_chgdets);
+
+ if (sensor.sense_chgdets)
+ event.args = 1;
+ else
+ event.args = 0;
+ /* send hardware event */
+ hw_event_send(HWE_DEF_PRIORITY, event);
+#endif
+}
+
+static void callback_low_battery(void)
+{
+#ifdef MXC_HWEVENT
+ struct mxc_hw_event event = { HWE_BAT_BATTERY_LOW, 0 };
+
+ pr_debug("In callback_low_battery\n");
+ /* send hardware event */
+ hw_event_send(HWE_DEF_PRIORITY, event);
+#endif
+}
+
+static void callback_power_fail(void)
+{
+#ifdef MXC_HWEVENT
+ struct mxc_hw_event event = { HWE_BAT_POWER_FAILED, 0 };
+
+ pr_debug("In callback_power_fail\n");
+ /* send hardware event */
+ hw_event_send(HWE_DEF_PRIORITY, event);
+#endif
+}
+
+static void callback_chg_overvoltage(void)
+{
+#ifdef MXC_HWEVENT
+ struct mxc_hw_event event = { HWE_BAT_CHARGER_OVERVOLTAGE, 0 };
+
+ pr_debug("In callback_chg_overvoltage\n");
+ /* send hardware event */
+ hw_event_send(HWE_DEF_PRIORITY, event);
+#endif
+}
+
+static void callback_chg_full(void)
+{
+#ifdef MXC_HWEVENT
+ t_sensor_bits sensor;
+ struct mxc_hw_event event = { HWE_BAT_CHARGER_FULL, 0 };
+
+ pr_debug("In callback_chg_full\n");
+
+ /* disable charge function */
+ pmic_batt_disable_charger(BATT_MAIN_CHGR);
+
+ /* get charger sensor */
+ pmic_get_sensors(&sensor);
+
+ /* if did not detect the charger */
+ if (sensor.sense_chgdets)
+ return;
+ /* send hardware event */
+ hw_event_send(HWE_DEF_PRIORITY, event);
+#endif
+}
+
/*!
* This is the suspend of power management for the pmic battery API.
* It suports SAVE and POWER_DOWN state.
@@ -131,9 +219,8 @@ PMIC_STATUS pmic_batt_enable_charger(t_batt_charger chgr,
mask = 0;
reg = 0;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
switch (chgr) {
case BATT_MAIN_CHGR:
@@ -183,10 +270,8 @@ PMIC_STATUS pmic_batt_disable_charger(t_batt_charger chgr)
mask = 0;
reg = 0;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
-
switch (chgr) {
case BATT_MAIN_CHGR:
val = BITFVAL(MC13783_BATT_DAC_DAC, 0) |
@@ -237,9 +322,8 @@ PMIC_STATUS pmic_batt_set_charger(t_batt_charger chgr,
mask = 0;
reg = 0;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
switch (chgr) {
case BATT_MAIN_CHGR:
@@ -287,9 +371,8 @@ PMIC_STATUS pmic_batt_get_charger_setting(t_batt_charger chgr,
reg = 0;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
switch (chgr) {
case BATT_MAIN_CHGR:
@@ -329,6 +412,93 @@ PMIC_STATUS pmic_batt_get_charger_setting(t_batt_charger chgr,
}
/*!
+ * This function is retrives the main battery voltage.
+ *
+ * @param b_voltage Output parameter for voltage setting.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_get_batt_voltage(unsigned short *b_voltage)
+{
+ t_channel channel;
+ unsigned short result[8];
+
+ if (suspend_flag == 1)
+ return PMIC_ERROR;
+ channel = BATTERY_VOLTAGE;
+ CHECK_ERROR(pmic_adc_convert(channel, result));
+ *b_voltage = result[0];
+
+ return PMIC_SUCCESS;
+}
+
+/*!
+ * This function is retrives the main battery current.
+ *
+ * @param b_current Output parameter for current setting.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_get_batt_current(unsigned short *b_current)
+{
+ t_channel channel;
+ unsigned short result[8];
+
+ if (suspend_flag == 1)
+ return PMIC_ERROR;
+
+ channel = BATTERY_CURRENT;
+ CHECK_ERROR(pmic_adc_convert(channel, result));
+ *b_current = result[0];
+
+ return PMIC_SUCCESS;
+}
+
+/*!
+ * This function is retrives the main battery temperature.
+ *
+ * @param b_temper Output parameter for temperature setting.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_get_batt_temperature(unsigned short *b_temper)
+{
+ t_channel channel;
+ unsigned short result[8];
+
+ if (suspend_flag == 1)
+ return PMIC_ERROR;
+
+ channel = GEN_PURPOSE_AD5;
+ CHECK_ERROR(pmic_adc_convert(channel, result));
+ *b_temper = result[0];
+
+ return PMIC_SUCCESS;
+}
+
+/*!
+ * This function is retrives the main battery charging voltage.
+ *
+ * @param c_voltage Output parameter for charging voltage setting.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_get_charge_voltage(unsigned short *c_voltage)
+{
+ t_channel channel;
+ unsigned short result[8];
+
+ if (suspend_flag == 1)
+ return PMIC_ERROR;
+
+ channel = CHARGE_VOLTAGE;
+ CHECK_ERROR(pmic_adc_convert(channel, result));
+ *c_voltage = result[0];
+
+ return PMIC_SUCCESS;
+}
+
+/*!
* This function is retrives the main battery charging current.
*
* @param c_current Output parameter for charging current setting.
@@ -340,9 +510,8 @@ PMIC_STATUS pmic_batt_get_charge_current(unsigned short *c_current)
t_channel channel;
unsigned short result[8];
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
channel = CHARGE_CURRENT;
CHECK_ERROR(pmic_adc_convert(channel, result));
@@ -382,9 +551,8 @@ PMIC_STATUS pmic_batt_bp_enable_eol(t_bp_threshold typical)
{
unsigned int val, mask;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
val = BITFVAL(MC13783_BATT_DAC_EOL_CMP_EN,
MC13783_BATT_DAC_EOL_CMP_EN_ENABLE) |
@@ -406,9 +574,8 @@ PMIC_STATUS pmic_batt_disable_eol(void)
{
unsigned int val, mask;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
val = BITFVAL(MC13783_BATT_DAC_EOL_CMP_EN,
MC13783_BATT_DAC_EOL_CMP_EN_DISABLE);
@@ -430,9 +597,9 @@ PMIC_STATUS pmic_batt_disable_eol(void)
PMIC_STATUS pmic_batt_set_out_control(t_control control)
{
unsigned int val, mask;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
+
switch (control) {
case CONTROL_HARDWARE:
val = BITFVAL(MC13783_BATT_DAC_FETOVRD_EN, 0) |
@@ -471,12 +638,12 @@ PMIC_STATUS pmic_batt_set_threshold(int threshold)
{
unsigned int val, mask;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
- if (threshold > BAT_THRESHOLD_MAX) {
+
+ if (threshold > BAT_THRESHOLD_MAX)
return PMIC_PARAMETER_ERROR;
- }
+
val = BITFVAL(MC13783_BATT_DAC_OVCTRL, threshold);
mask = BITFMASK(MC13783_BATT_DAC_OVCTRL);
CHECK_ERROR(pmic_write_reg(REG_CHARGER, val, mask));
@@ -495,9 +662,8 @@ PMIC_STATUS pmic_batt_led_control(bool on)
{
unsigned val, mask;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
val = BITFVAL(MC13783_BATT_DAC_LED_EN, on);
mask = BITFMASK(MC13783_BATT_DAC_LED_EN);
@@ -519,9 +685,8 @@ PMIC_STATUS pmic_batt_set_reverse_supply(bool enable)
{
unsigned val, mask;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
val = BITFVAL(MC13783_BATT_DAC_REVERSE_SUPPLY, enable);
mask = BITFMASK(MC13783_BATT_DAC_REVERSE_SUPPLY);
@@ -543,9 +708,8 @@ PMIC_STATUS pmic_batt_set_unregulated(bool enable)
{
unsigned val, mask;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
val = BITFVAL(MC13783_BATT_DAC_UNREGULATED, enable);
mask = BITFMASK(MC13783_BATT_DAC_UNREGULATED);
@@ -568,9 +732,8 @@ PMIC_STATUS pmic_batt_set_5k_pull(bool enable)
{
unsigned val, mask;
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
val = BITFVAL(MC13783_BATT_DAC_5K, enable);
mask = BITFMASK(MC13783_BATT_DAC_5K);
@@ -598,7 +761,7 @@ PMIC_STATUS mc13783_battery_event(t_batt_event event, void *callback, bool sub)
bat_callback.param = NULL;
switch (event) {
case BAT_IT_CHG_DET:
- bat_event = EVENT_WLOWI;
+ bat_event = EVENT_CHGDETI;
break;
case BAT_IT_CHG_OVERVOLT:
bat_event = EVENT_CHGOVI;
@@ -619,9 +782,9 @@ PMIC_STATUS mc13783_battery_event(t_batt_event event, void *callback, bool sub)
return PMIC_PARAMETER_ERROR;
}
if (sub == true) {
- CHECK_ERROR(pmic_event_subscribe(event, bat_callback));
+ CHECK_ERROR(pmic_event_subscribe(bat_event, bat_callback));
} else {
- CHECK_ERROR(pmic_event_unsubscribe(event, bat_callback));
+ CHECK_ERROR(pmic_event_unsubscribe(bat_event, bat_callback));
}
return 0;
}
@@ -636,9 +799,9 @@ PMIC_STATUS mc13783_battery_event(t_batt_event event, void *callback, bool sub)
*/
PMIC_STATUS pmic_batt_event_subscribe(t_batt_event event, void *callback)
{
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
+
return mc13783_battery_event(event, callback, true);
}
@@ -652,9 +815,9 @@ PMIC_STATUS pmic_batt_event_subscribe(t_batt_event event, void *callback)
*/
PMIC_STATUS pmic_batt_event_unsubscribe(t_batt_event event, void *callback)
{
- if (suspend_flag == 1) {
+ if (suspend_flag == 1)
return PMIC_ERROR;
- }
+
return mc13783_battery_event(event, callback, false);
}
@@ -672,6 +835,7 @@ static int pmic_battery_ioctl(struct inode *inode, struct file *file,
{
t_charger_setting *chgr_setting = NULL;
unsigned short c_current;
+ unsigned int bc_info;
t_eol_setting *eol_setting;
if (_IOC_TYPE(cmd) != 'p')
@@ -747,12 +911,58 @@ static int pmic_battery_ioctl(struct inode *inode, struct file *file,
kfree(chgr_setting);
break;
+ case PMIC_BATT_GET_CHARGER_SENSOR:
+ {
+ t_sensor_bits sensor;
+ pmic_get_sensors(&sensor);
+ if (copy_to_user
+ ((unsigned int *)arg, &sensor.sense_chgdets,
+ sizeof(unsigned int)))
+ return -EFAULT;
+
+ break;
+ }
+ case PMIC_BATT_GET_BATTERY_VOLTAGE:
+ CHECK_ERROR(pmic_batt_get_batt_voltage(&c_current));
+ bc_info = (unsigned int)c_current * 2300 / 1023 + 2400;
+ if (copy_to_user((unsigned int *)arg, &bc_info,
+ sizeof(unsigned int)))
+ return -EFAULT;
+
+ break;
+
+ case PMIC_BATT_GET_BATTERY_CURRENT:
+ CHECK_ERROR(pmic_batt_get_batt_current(&c_current));
+ bc_info = (unsigned int)c_current * 5750 / 1023;
+ if (copy_to_user((unsigned int *)arg, &bc_info,
+ sizeof(unsigned int)))
+ return -EFAULT;
+ break;
+
+ case PMIC_BATT_GET_BATTERY_TEMPERATURE:
+ CHECK_ERROR(pmic_batt_get_batt_temperature(&c_current));
+ bc_info = (unsigned int)c_current;
+ if (copy_to_user((unsigned int *)arg, &bc_info,
+ sizeof(unsigned int)))
+ return -EFAULT;
+
+ break;
+
+ case PMIC_BATT_GET_CHARGER_VOLTAGE:
+ CHECK_ERROR(pmic_batt_get_charge_voltage(&c_current));
+ bc_info = (unsigned int)c_current * 23000 / 1023;
+ if (copy_to_user((unsigned int *)arg, &bc_info,
+ sizeof(unsigned int)))
+ return -EFAULT;
+
+ break;
+
case PMIC_BATT_GET_CHARGER_CURRENT:
CHECK_ERROR(pmic_batt_get_charge_current(&c_current));
- if (copy_to_user((unsigned char *)arg, &c_current,
- sizeof(unsigned char *))) {
+ bc_info = (unsigned int)c_current * 5750 / 1023;
+ if (copy_to_user((unsigned int *)arg, &bc_info,
+ sizeof(unsigned int)))
return -EFAULT;
- }
break;
@@ -821,7 +1031,60 @@ static int pmic_battery_open(struct inode *inode, struct file *file)
return -ERESTARTSYS;
}
}
+
+ /* check open count, if open firstly, register callbacks */
+ down(&count_mutex);
+ if (open_count++ > 0) {
+ up(&count_mutex);
+ return 0;
+ }
+
+ pr_debug("Subscribe the callbacks\n");
+ /* register battery event callback */
+ if (pmic_batt_event_subscribe(BAT_IT_CHG_DET, callback_chg_detect)) {
+ pr_debug("Failed to subscribe the charger detect callback\n");
+ goto event_err1;
+ }
+ if (pmic_power_event_sub(PWR_IT_LOBATLI, callback_power_fail)) {
+ pr_debug("Failed to subscribe the power failed callback\n");
+ goto event_err2;
+ }
+ if (pmic_power_event_sub(PWR_IT_LOBATHI, callback_low_battery)) {
+ pr_debug("Failed to subscribe the low battery callback\n");
+ goto event_err3;
+ }
+ if (pmic_batt_event_subscribe
+ (BAT_IT_CHG_OVERVOLT, callback_chg_overvoltage)) {
+ pr_debug("Failed to subscribe the low battery callback\n");
+ goto event_err4;
+ }
+ if (pmic_batt_event_subscribe
+ (BAT_IT_BELOW_THRESHOLD, callback_chg_full)) {
+ pr_debug("Failed to subscribe the charge full callback\n");
+ goto event_err5;
+ }
+
+ up(&count_mutex);
+
return 0;
+
+ /* un-subscribe the event callbacks */
+event_err5:
+ pmic_batt_event_unsubscribe(BAT_IT_CHG_OVERVOLT,
+ callback_chg_overvoltage);
+event_err4:
+ pmic_power_event_unsub(PWR_IT_LOBATHI, callback_low_battery);
+event_err3:
+ pmic_power_event_unsub(PWR_IT_LOBATLI, callback_power_fail);
+event_err2:
+ pmic_batt_event_unsubscribe(BAT_IT_CHG_DET, callback_chg_detect);
+event_err1:
+
+ open_count--;
+ up(&count_mutex);
+
+ return -EFAULT;
+
}
/*!
@@ -840,6 +1103,23 @@ static int pmic_battery_release(struct inode *inode, struct file *file)
return -ERESTARTSYS;
}
}
+
+ /* check open count, if open firstly, register callbacks */
+ down(&count_mutex);
+ if (--open_count == 0) {
+ /* unregister these event callback */
+ pr_debug("Unsubscribe the callbacks\n");
+ pmic_batt_event_unsubscribe(BAT_IT_BELOW_THRESHOLD,
+ callback_chg_full);
+ pmic_batt_event_unsubscribe(BAT_IT_CHG_OVERVOLT,
+ callback_chg_overvoltage);
+ pmic_power_event_unsub(PWR_IT_LOBATHI, callback_low_battery);
+ pmic_power_event_unsub(PWR_IT_LOBATLI, callback_power_fail);
+ pmic_batt_event_unsubscribe(BAT_IT_CHG_DET,
+ callback_chg_detect);
+ }
+ up(&count_mutex);
+
return 0;
}
@@ -888,6 +1168,9 @@ static int pmic_battery_probe(struct platform_device *pdev)
goto err_out2;
}
+ pmic_batt_led_control(true);
+ pmic_batt_set_5k_pull(true);
+
printk(KERN_INFO "PMIC Battery successfully probed\n");
return ret;
diff --git a/drivers/mxc/pmic/mc13783/pmic_power.c b/drivers/mxc/pmic/mc13783/pmic_power.c
index 133e8014fa13..40630332a3ab 100644
--- a/drivers/mxc/pmic/mc13783/pmic_power.c
+++ b/drivers/mxc/pmic/mc13783/pmic_power.c
@@ -21,7 +21,7 @@
/*
* Includes
*/
-
+#define DEBUG
#include <linux/platform_device.h>
#include <asm/ioctl.h>
#include <asm/arch/pmic_power.h>
@@ -29,6 +29,14 @@
#include "pmic_power_defs.h"
+#ifdef CONFIG_MXC_HWEVENT
+#include <../drivers/mxc/hw_event/mxc_hw_event.h>
+#endif
+
+#include <asm/mach-types.h>
+
+#define MC13783_REGCTRL_GPOx_MASK 0x18000
+
static bool VBKUP1_EN = false;
static bool VBKUP2_EN = false;
@@ -3036,6 +3044,26 @@ PMIC_STATUS pmic_power_event_unsub(t_pwr_int event, void *callback)
return pmic_power_event(event, callback, false);
}
+void pmic_power_key_callback(void)
+{
+#ifdef MXC_HWEVENT
+ /*read the power key is pressed or up */
+ t_sensor_bits sense;
+ struct mxc_hw_event event = { HWE_POWER_KEY, 0 };
+
+ pmic_get_sensors(&sense);
+ if (sense.sense_onofd1s) {
+ pr_debug("PMIC Power key up\n");
+ event.args = PWRK_UNPRESS;
+ } else {
+ pr_debug("PMIC Power key pressed\n");
+ event.args = PWRK_PRESS;
+ }
+ /* send hw event */
+ hw_event_send(HWE_DEF_PRIORITY, event);
+#endif
+}
+
/*
* Init and Exit
*/
@@ -3059,10 +3087,12 @@ static struct platform_driver pmic_power_driver_ldm = {
static int __init pmic_power_init(void)
{
pr_debug("PMIC Power driver loading..\n");
+ pmic_power_event_sub(PWR_IT_ONOFD1I, pmic_power_key_callback);
return platform_driver_register(&pmic_power_driver_ldm);
}
static void __exit pmic_power_exit(void)
{
+ pmic_power_event_unsub(PWR_IT_ONOFD1I, pmic_power_key_callback);
platform_driver_unregister(&pmic_power_driver_ldm);
pr_debug("PMIC Power driver successfully unloaded\n");
}
@@ -3071,7 +3101,7 @@ static void __exit pmic_power_exit(void)
* Module entry points
*/
-subsys_initcall(pmic_power_init);
+subsys_initcall_sync(pmic_power_init);
module_exit(pmic_power_exit);
MODULE_DESCRIPTION("pmic_power driver");
diff --git a/include/asm-arm/arch-mxc/pmic_battery.h b/include/asm-arm/arch-mxc/pmic_battery.h
index 39805b72e530..61dbdfc023c4 100644
--- a/include/asm-arm/arch-mxc/pmic_battery.h
+++ b/include/asm-arm/arch-mxc/pmic_battery.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -85,6 +85,32 @@
* Argument type: int
*/
#define PMIC_BATT_SET_THRESHOLD _IOW('p', 0xc9, int)
+
+/*!
+ * Get the charger voltage.
+ * Argument type: int
+ */
+#define PMIC_BATT_GET_CHARGER_VOLTAGE _IOR('p', 0xca, int)
+/*!
+ * Get the battery voltage.
+ * Argument type: int
+ */
+#define PMIC_BATT_GET_BATTERY_VOLTAGE _IOR('p', 0xcb, int)
+/*!
+ * Get the battery current.
+ * Argument type: int
+ */
+#define PMIC_BATT_GET_BATTERY_CURRENT _IOR('p', 0xcc, int)
+/*!
+ * Get the charger sensor.
+ * Argument type: int
+ */
+#define PMIC_BATT_GET_CHARGER_SENSOR _IOR('p', 0xcd, int)
+/*!
+ * Get the battery temperature.
+ * Argument type: int
+ */
+#define PMIC_BATT_GET_BATTERY_TEMPERATURE _IOR('p', 0xce, int)
/*! @} */
/*!
@@ -154,6 +180,20 @@ typedef enum {
BAT_IT_BELOW_THRESHOLD,
} t_batt_event;
+/*START: for 3ds hw event*/
+/*!
+ * Battery event type enum
+ */
+enum {
+ BAT_EVENT_CHARGER_PLUG = 0x01,
+ BAT_EVENT_CHARGER_UNPLUG = 0x02,
+ BAT_EVENT_CHARGER_OVERVOLTAGE = 0x04,
+ BAT_EVENT_BATTERY_LOW = 0x08,
+ BAT_EVENT_POWER_FAILED = 0x10,
+ BAT_EVENT_CHARGER_FULL = 0x20,
+} t_bat_event;
+/*END: for 3ds hw event*/
+
/*!
* This structure is used for the following battery changer control
* IOCTLs:
diff --git a/include/asm-arm/arch-mxc/pmic_status.h b/include/asm-arm/arch-mxc/pmic_status.h
index 55dbe155ea56..a9287292e7db 100644
--- a/include/asm-arm/arch-mxc/pmic_status.h
+++ b/include/asm-arm/arch-mxc/pmic_status.h
@@ -13,7 +13,9 @@
#ifndef __ASM_ARCH_MXC_PMIC_STATUS_H__
#define __ASM_ARCH_MXC_PMIC_STATUS_H__
#include <asm-generic/errno-base.h>
+#ifdef __KERNEL__
#include <asm/uaccess.h> /* copy_{from,to}_user() */
+#endif
/*!
* @file arch-mxc/pmic_status.h
* @brief PMIC APIs return code definition.