summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/omap3_h1.dts15
-rw-r--r--arch/arm/mach-omap2/board-omap3h1.c10
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h6
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c2
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c66
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c70
-rw-r--r--drivers/leds/leds-lm3530.c54
-rw-r--r--drivers/power/bq27x00_battery.c40
-rw-r--r--drivers/rtc/rtc-tps65910.c5
-rw-r--r--include/linux/led-lm3530.h4
10 files changed, 105 insertions, 167 deletions
diff --git a/arch/arm/boot/dts/omap3_h1.dts b/arch/arm/boot/dts/omap3_h1.dts
index b83d1bdb0bd..b8c949698ae 100644
--- a/arch/arm/boot/dts/omap3_h1.dts
+++ b/arch/arm/boot/dts/omap3_h1.dts
@@ -75,8 +75,9 @@
/* listed below will be reported as the wakeup reason */
/* */
/* off IRQ handle */
- ti,pad_irq = <0x150 88 1>, /* 72 + 16, uart1 - BT input */
- <0x9f6 143 1>, /* mpu6515 irq pin - is this offset correct? */
+ ti,pad_irq = <0x150 88 1>, /* 72 + 16, uart1 - BT input */
+ <0x9f6 143 1>, /* mpu6515 irq pin - is this offset correct? */
+ <0x9ea 122 1>, /* bq27400 chg irq8 */
<0x9f4 123 1>, /* BT host wake */
<0x1b0 23 1>; /* sys_nirq */
};
@@ -232,7 +233,15 @@
pinctrl-single,pins = <
0x006 0x008 /* SYS_CLKREQ, MODE0 | PULLDOWN */
0x018 0x000 /* SYS_OFF_MODE, MODE0 */
- 0x01a 0x10c /* SYS_CLKOUT1, MODE4 | INPUT_PULLDOWN */
+ /* Fuel gauge interrupt */
+ 0x01a 0x4104 /* SYS_CLKOUT1, MODE4 | OMAP_PIN_INPUT */
+
+ /*
+ * lm3530 PWM pin, gpio128
+ * gpio128, MODE4 | OFFPULLDOWN | OFFENABLE | OFFOUTENABLE |
+ * OUTPUT
+ */
+ 0x058 0x1604
/* Wakeup from Bluetooth */
0x024 0x410C /* JTAG_EMU0, OMAP_MUX_MODE4 | OMAP_PIN_INPUT |
diff --git a/arch/arm/mach-omap2/board-omap3h1.c b/arch/arm/mach-omap2/board-omap3h1.c
index 071af9b51c3..c1009f3b7e2 100644
--- a/arch/arm/mach-omap2/board-omap3h1.c
+++ b/arch/arm/mach-omap2/board-omap3h1.c
@@ -79,6 +79,7 @@
#define TPS_SYS_NIRQ 0
#define USB_IRQ 124
#define USB_CS 17
+#define CHG_GPOUT 10
#define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */
#define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */
@@ -90,6 +91,8 @@
#define LCD_RESET_GPIO 122
#endif
+#define BACKLIGHT_PWM_GPIO 128
+
static struct of_device_id omap_dt_match_table[] __initdata = {
{ .compatible = "olio,omap3-h1", },
{ .compatible = "simple-bus", },
@@ -198,7 +201,7 @@ static struct mpu_platform_data mpu_data = {
#endif
static struct lm3530_platform_data omap3h1_backlight_platform_data = {
- .mode = LM3530_BL_MODE_MANUAL,
+ .mode = LM3530_BL_MODE_SIMPLE_MANUAL,
//.als_input_mode = LM3530_INPUT_ALS1,
.max_current = LM3530_FS_CURR_29mA,
//.pwm_pol_hi = true,
@@ -211,6 +214,7 @@ static struct lm3530_platform_data omap3h1_backlight_platform_data = {
//.als_vmin = 730, /* mV */
//.als_vmax = 10a20, /* mV */
.brt_val = 0x64, /* initial brightness */
+ .pwm_gpio = BACKLIGHT_PWM_GPIO,
};
@@ -418,6 +422,10 @@ static int __init omap3_h1_i2c_init(void)
omap3h1_i2c1_board_info[1].irq = acc_irq;
#endif
+#if defined (CONFIG_MACH_OMAP3_H1_PV)
+ omap3h1_i2c2_board_info[4].irq = gpio_to_irq(CHG_GPOUT);
+#endif
+
gpio_request_one(USB_CS, GPIOF_OUT_INIT_HIGH, "USB on");
/* Register buses */
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h
index 4c6fc426fc4..ba971628496 100644
--- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h
+++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h
@@ -137,14 +137,12 @@ struct lsm6ds3_data {
int wake_lock_initialized;
struct wake_lock wlock;
struct wake_lock tap_wlock;
-#define RESUME_NORMAL 1
-#define RESUME_FROM_INACTIVE 3
u8 first_irq_from_resume;
u8 reg_read;
#define SIXD_MASK_VALID_BITS (0x3f)
u8 sixd_mask;
u8 int1_save;
- int inactive_wait;
+
u8 *fifo_data;
u8 sensors_enabled;
u8 gyro_selftest_status;
@@ -214,7 +212,7 @@ struct lsm6ds3_sensor_data {
u8 sindex;
u8 *buffer_data;
};
-void st_lsm6ds3_set_inactive_detection(struct lsm6ds3_data *cdata, int enable);
+
int st_lsm6ds3_write_data_with_mask(struct lsm6ds3_data *cdata,
u8 reg_addr, u8 mask, u8 data, bool b_lock);
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c
index ad5cd7b14cd..87cea6f349a 100644
--- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c
+++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c
@@ -194,7 +194,7 @@ void st_lsm6ds3_read_fifo(struct lsm6ds3_data *cdata, bool check_fifo_len, bool
#endif
cdata->accel_timestamp = cdata->timestamp - (cdata->accel_deltatime * (read_len/3)); //backdate timestamp
if(update_discard){
- dev_dbg(cdata->dev, "first accel timestamp:%lld last:%lld ", cdata->accel_timestamp, cdata->timestamp);
+ dev_info(cdata->dev, "first accel timestamp:%lld last:%lld ", cdata->accel_timestamp, cdata->timestamp);
}
}
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c
index a33a6c91d43..499fda71e59 100644
--- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c
+++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c
@@ -874,10 +874,6 @@ int st_lsm6ds3_set_drdy_irq(struct lsm6ds3_sensor_data *sdata, bool state)
{
u8 reg_addr, mask, value;
- if((state && sdata->cdata->inactive_wait) && (sdata->sindex != ST_INDIO_DEV_ACCEL)){//allow disables but not enables, except for accelerometer
- dev_info(sdata->cdata->dev, "drdy setup ignored, inactive_wait:%i", sdata->sindex);
- return 0;
- }
if (state)
value = ST_LSM6DS3_EN_BIT;
else
@@ -915,9 +911,6 @@ int st_lsm6ds3_set_drdy_irq(struct lsm6ds3_sensor_data *sdata, bool state)
mask = ST_LSM6DS3_FIFO_THR_IRQ_MASK;
break;
case ST_INDIO_DEV_SIGN_MOTION:
- if(state && sdata->cdata->inactive_wait){
- return 0;
- }
if (sdata->cdata->sensors_enabled &
(1 << ST_INDIO_DEV_STEP_DETECTOR)){
dev_err(sdata->cdata->dev, "can't set up significant motion irq, step detector enabled");
@@ -1575,10 +1568,6 @@ static int st_lsm6ds3_init_sensor(struct lsm6ds3_data *cdata)
#define ST_LSM6DS3_CTRL8_LPF_ON_ACCEL 0x80
#define ST_LSM6DS3_CTRL4_ADDR 0x13
#define ST_LSM6DS3_CTRL4_STOP_ON_FTH_MASK 0x1
-//inactivity stuff
-#define ST_LSM6DS3_WAKE_UP_THR_ADDR 0x5B
-#define ST_LSM6DS3_WAKE_UP_DUR_ADDR 0x5C
-
regval = 0x50;//tap threshold
err = sdata->cdata->tf->write(sdata->cdata,
ST_LSM6DS3_TAP_THS_6D_ADDR,
@@ -1589,8 +1578,8 @@ static int st_lsm6ds3_init_sensor(struct lsm6ds3_data *cdata)
ST_LSM6DS3_INT_DUR2_ADDR,
1, &regval, false);
- regval = 0x12; //enable slop_fd to get lpf2 for 6d
- // also enable z tap
+ regval = 0x13; //enable slop_fd to get lpf2 for 6d
+ // also enable z tap and latch irqs
err = sdata->cdata->tf->write(sdata->cdata,
ST_LSM6DS3_TAP_CFG_ADDR,
1, &regval, false);
@@ -1599,17 +1588,6 @@ static int st_lsm6ds3_init_sensor(struct lsm6ds3_data *cdata)
err = sdata->cdata->tf->write(sdata->cdata,
ST_LSM6DS3_CTRL8_ADDR ,
1, &regval, false);
-
-
- regval = 0x42;
-#if 0
- err = sdata->cdata->tf->write(sdata->cdata,
- ST_LSM6DS3_WAKE_UP_THR_ADDR,
- 1, &regval, false);
-#endif
- err = sdata->cdata->tf->write(sdata->cdata,
- ST_LSM6DS3_WAKE_UP_DUR_ADDR,
- 1, &regval, false);
if (err < 0)
goto st_lsm6ds3_init_sensor_mutex_unlock;
@@ -1629,20 +1607,6 @@ st_lsm6ds3_init_sensor_mutex_unlock:
return err;
}
-void st_lsm6ds3_set_inactive_detection(struct lsm6ds3_data *cdata, int enable)
-{
- u8 regval = 0;
-
- if(enable)
- regval = 0x42;
- else
- regval = 0x00;
-
- cdata->tf->write(cdata, ST_LSM6DS3_WAKE_UP_THR_ADDR,
- 1, &regval, false);
-
-}
-
static int st_lsm6ds3_set_selftest(struct lsm6ds3_sensor_data *sdata, int index)
{
int err;
@@ -2183,7 +2147,6 @@ int st_lsm6ds3_common_probe(struct lsm6ds3_data *cdata, int irq)
cdata->fifo_data = 0;
cdata->samples_to_keep_on_wake = ST_LSM6DS3_SAMPLES_ON_WAKE_DEFAULT;
- cdata->inactive_wait = 0;
err = cdata->tf->read(cdata, ST_LSM6DS3_WAI_ADDRESS, 1, &wai, true);
if (err < 0) {
@@ -2384,6 +2347,9 @@ int st_lsm6ds3_common_suspend(struct lsm6ds3_data *cdata)
reg_value = 0x44;
err = cdata->tf->write(cdata,
ST_LSM6DS3_MD1_ADDR, 1, &reg_value, true);
+ err = cdata->tf->read(cdata,
+ ST_LSM6DS3_MD1_ADDR, 1, &reg_value, true);
+ dev_info(cdata->dev, "before suspend md1: %x, err:%i", reg_value, err);
err = cdata->tf->read(cdata,
0xd, 1, &reg_value, true);
@@ -2420,19 +2386,6 @@ int st_lsm6ds3_common_suspend(struct lsm6ds3_data *cdata)
0x13, 1, &reg_value, true);
dev_info(cdata->dev, "before suspend 0x13 ctrl4: %x err:%i", reg_value, err);
#endif
- if(cdata->inactive_wait){
- reg_value = 0x80;
- err = cdata->tf->write(cdata,
- ST_LSM6DS3_MD1_ADDR, 1, &reg_value, true);
- }
-
- err = cdata->tf->read(cdata,
- ST_LSM6DS3_MD1_ADDR, 1, &reg_value, true);
- dev_info(cdata->dev, "before suspend md1: %x, err:%i", reg_value, err);
-
- err = cdata->tf->read(cdata,
- ST_LSM6DS3_INT1_ADDR, 1, &reg_value, true);
- dev_info(cdata->dev, "before suspend int1_ctrl: %x, err:%i", reg_value, err);
return 0;
}
@@ -2445,18 +2398,13 @@ int st_lsm6ds3_common_resume(struct lsm6ds3_data *cdata)
struct lsm6ds3_sensor_data *sdata;
u8 reg_value;
- if(cdata->inactive_wait){
- dev_info(cdata->dev, "First wake from hyperactivity wait");
- cdata->inactive_wait = 0;
- st_lsm6ds3_set_inactive_detection(cdata, false);
- }
for (i = 0; i < ST_INDIO_DEV_NUM; i++) {
- if ((i == ST_INDIO_DEV_SIGN_MOTION && !cdata->int1_save) || (i == ST_INDIO_DEV_TILT))
+ if ((i == ST_INDIO_DEV_SIGN_MOTION) || (i == ST_INDIO_DEV_TILT))
continue;
sdata = iio_priv(cdata->indio_dev[i]);
- if(((i == ST_INDIO_DEV_ACCEL)||(i == ST_INDIO_DEV_SIGN_MOTION)) && cdata->int1_save == 1 ){
+ if(i == ST_INDIO_DEV_ACCEL && cdata->int1_save == 1 ){
//todo fix how this is set, we're always clearing and setting
err = st_lsm6ds3_set_drdy_irq(sdata, true);
cdata->int1_save = 0;
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c
index a2df1d2990b..9fe257039bb 100644
--- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c
+++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c
@@ -20,7 +20,6 @@
#include <linux/iio/events.h>
#include <linux/wakelock.h>
#include <linux/wakeup_reason.h>
-#include <linux/kfifo.h>
#include "st_lsm6ds3.h"
@@ -40,9 +39,7 @@
#define ST_LSM6DS3_6D_SRC_ADDR 0x1d
-#define WAKE_LOG_EVENTS 8 //must be power of 2 for kfifo
-static DECLARE_KFIFO(wake_time_fifo, s64, WAKE_LOG_EVENTS);
-#define HYPERACTIVITY_WINDOW_NS 5000000000L
+
static struct workqueue_struct *st_lsm6ds3_wq;
@@ -51,32 +48,6 @@ void st_lsm6ds3_flush_works()
flush_workqueue(st_lsm6ds3_wq);
}
-int hyperactivity_check(struct lsm6ds3_data *cdata)
-{
- int i, fifo_len;
- int recent_count = 0;
- struct timespec ts;
- s64 ctime;
- s64 wtime[WAKE_LOG_EVENTS] = {0};
- get_monotonic_boottime(&ts);
- ctime = timespec_to_ns(&ts);
- fifo_len = kfifo_len(&wake_time_fifo);
- dev_dbg(cdata->dev, "HYP_CHECK FIFO_LEN: %i/%i, time:%lld", fifo_len, kfifo_size(&wake_time_fifo), ctime);
- if(fifo_len < WAKE_LOG_EVENTS)
- return 0;
-
- kfifo_out(&wake_time_fifo, wtime, WAKE_LOG_EVENTS);
- for(i=0; i < WAKE_LOG_EVENTS; i++){
- dev_dbg(cdata->dev, "wtime[%i]:%lld", i, wtime[i]);
- if(ctime - wtime[i] < HYPERACTIVITY_WINDOW_NS){
- recent_count++;
- kfifo_in(&wake_time_fifo, &wtime[i], 1);
- }
- }
- dev_dbg(cdata->dev, "recent count:%i", recent_count);
- return (recent_count == WAKE_LOG_EVENTS);
-}
-
irqreturn_t st_lsm6ds3_save_timestamp(int irq, void *private)
{
struct timespec ts;
@@ -99,21 +70,17 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
u8 src_value = 0x00, src_fifo = 0x00;
u8 d6d_event = 0;
u8 tap_event = 0;
- int woken_from_sleep = 0;
- int hyperactive = 0;
+ int wake_irq;
cdata = container_of((struct work_struct *)data_work,
struct lsm6ds3_data, data_work);
-
- if(cdata->first_irq_from_resume && last_wakeup_reason_test(cdata->irq)){
- //take_wake_lock to give app enough time from wakeup
- woken_from_sleep = 1;
- wake_lock_timeout(&cdata->wlock,msecs_to_jiffies(1000));
- }
- mutex_lock(&cdata->fifo_lock);
+ wake_irq = last_wakeup_reason_test(cdata->irq);
+ if(!wake_lock_active(&cdata->wlock))
+ wake_lock(&cdata->wlock);
+ mutex_lock(&cdata->fifo_lock);
cdata->tf->read(cdata, ST_LSM6DS3_6D_SRC_ADDR, 1, &d6d_src_reg, true);
cdata->tf->read(cdata, ST_LSM6DS3_TAP_SRC_ADDR, 1, &tap_src_reg, true);
cdata->tf->read(cdata, ST_LSM6DS3_SRC_FUNC_ADDR, 1, &src_value, true);
@@ -144,7 +111,7 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
dev_info(cdata->dev, "Ignoring tap");
}
}
- if(woken_from_sleep){
+ if(cdata->first_irq_from_resume && wake_irq){
dev_info(cdata->dev, "First IRQ from a RESUME");
if(!d6d_event && !tap_event){
dev_info(cdata->dev, "No event from first resume, assuming lost TAP");
@@ -161,13 +128,11 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
st_lsm6ds3_read_fifo(cdata, true, true);
}
else{
- st_lsm6ds3_read_fifo(cdata, true, true);
+ st_lsm6ds3_read_fifo(cdata, true, false);
}
}
//significant motion event processing
- if(!cdata->inactive_wait && (d6d_event || tap_event)){
- kfifo_in(&wake_time_fifo, &cdata->timestamp, 1);
- hyperactive = hyperactivity_check(cdata);
+ if(d6d_event || tap_event){
dev_info(cdata->dev, "Sending sig mot event; ready:%i",cdata->sign_motion_event_ready);
wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(1500));
iio_push_event(cdata->indio_dev[
@@ -209,19 +174,10 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
cdata->timestamp);
}
- if(hyperactive){
- uint8_t reg_value;
- int err;
-
- dev_info(cdata->dev, "Hyperactivity triggered, masking irqs except inactivity and fifo");
- cdata->inactive_wait = 1;
- reg_value = 0x80;//fifo is in another register
- err = cdata->tf->write(cdata,
- 0x5e, 1, &reg_value, true);
- st_lsm6ds3_set_inactive_detection(cdata, 1);
- }
enable_irq(cdata->irq);
mutex_unlock(&cdata->fifo_lock);
+ if(wake_lock_active(&cdata->wlock))
+ wake_unlock(&cdata->wlock);
cdata->first_irq_from_resume = 0;
return;
@@ -239,8 +195,6 @@ int st_lsm6ds3_allocate_triggers(struct lsm6ds3_data *cdata,
return -EINVAL;
INIT_WORK(&cdata->data_work, st_lsm6ds3_irq_management);
- INIT_KFIFO(wake_time_fifo);
-
for (i = 0; i < ST_INDIO_DEV_NUM; i++) {
cdata->trig[i] = iio_trigger_alloc("%s-trigger",
@@ -257,7 +211,7 @@ int st_lsm6ds3_allocate_triggers(struct lsm6ds3_data *cdata,
}
err = request_threaded_irq(cdata->irq, st_lsm6ds3_save_timestamp, NULL,
- IRQF_TRIGGER_RISING, cdata->name, cdata);
+ IRQF_TRIGGER_HIGH, cdata->name, cdata);
if (err)
goto deallocate_trigger;
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index 41b5f574ad0..c3d4a69655f 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/regulator/consumer.h>
#include <linux/module.h>
+#include <linux/gpio.h>
#define LM3530_LED_DEV "lcd-backlight"
#define LM3530_NAME "lm3530-led"
@@ -92,6 +93,7 @@ struct lm3530_mode_map {
static struct lm3530_mode_map mode_map[] = {
{ "man", LM3530_BL_MODE_MANUAL },
+ { "man", LM3530_BL_MODE_SIMPLE_MANUAL },
{ "als", LM3530_BL_MODE_ALS },
{ "pwm", LM3530_BL_MODE_PWM },
};
@@ -246,6 +248,11 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
case LM3530_BL_MODE_MANUAL:
gen_config |= LM3530_ENABLE_I2C;
break;
+ case LM3530_BL_MODE_SIMPLE_MANUAL:
+ gen_config |= LM3530_ENABLE_I2C | LM3530_ENABLE_PWM_SIMPLE |
+ LM3530_ENABLE_PWM |
+ (pdata->pwm_pol_hi << LM3530_PWM_POL_SHIFT);
+ break;
case LM3530_BL_MODE_ALS:
gen_config |= LM3530_ENABLE_I2C;
lm3530_als_configure(pdata, &als);
@@ -317,6 +324,7 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
switch (drvdata->mode) {
case LM3530_BL_MODE_MANUAL:
+ case LM3530_BL_MODE_SIMPLE_MANUAL:
if (!drvdata->enable) {
err = lm3530_init_registers(drvdata);
@@ -471,6 +479,11 @@ static int lm3530_probe(struct i2c_client *client,
goto err_create_file;
}
+ if (gpio_request_one(drvdata->pdata->pwm_gpio,
+ GPIOF_DIR_OUT | GPIOF_EXPORT | GPIOF_INIT_HIGH,
+ "backlight gpio"))
+ dev_err(&client->dev, "Failed to request gpio:\n");
+
return 0;
err_create_file:
@@ -507,46 +520,6 @@ static void lm3530_shutdown(struct i2c_client *client)
return;
}
-/**
- * lm3530_suspend - suspend backlight
- *
- * For now, off. Should also save the previous setting.
- */
-
-static int lm3530_suspend(struct device *dev) {
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
-
- printk ("OLIO %s:%s Suspending\n", __FILE__, __FUNCTION__);
-
- lm3530_brightness_set(led_cdev, LED_OFF);
-
- return 0;
-}
-
-/**
- * lm3530_resume - reset backlight
- *
- * Turn the backlight on again (Does android take care of this for us?)
- * For now, leave this as a no-op - Android turns on the lights.
- */
-
-static int lm3530_resume(struct device *dev) {
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
-
- printk ("OLIO %s:%s Resuming\n", __FILE__, __FUNCTION__);
-
- /* lm3530_brightness_set(led_cdev, 100); */
-
- return 0;
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-static const struct dev_pm_ops lm3530_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(lm3530_suspend, lm3530_resume)
-};
-
static const struct i2c_device_id lm3530_id[] = {
{LM3530_NAME, 0},
{}
@@ -561,7 +534,6 @@ static struct i2c_driver lm3530_i2c_driver = {
.driver = {
.name = LM3530_NAME,
.owner = THIS_MODULE,
- .pm = &lm3530_pm_ops,
},
};
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 7bed61e6229..c10f48b20c8 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -37,8 +37,11 @@
#include <linux/power_supply.h>
#include <linux/idr.h>
#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
+#include <linux/wakelock.h>
#include <linux/power/bq27x00_battery.h>
@@ -67,6 +70,8 @@ enum bq27xxx_reg_index {
NUM_REGS
};
+struct wake_lock chg_wake_lock;
+
/* bq27500 registers */
static __initdata u8 bq27500_regs[NUM_REGS] = {
0x00, /* CONTROL */
@@ -279,6 +284,7 @@ struct bq27x00_device_info {
struct device *dev;
int id;
enum bq27x00_chip chip;
+ int irq;
struct bq27x00_reg_cache cache;
int charge_design_full;
@@ -1345,6 +1351,16 @@ static void bq27x00_external_power_changed(struct power_supply *psy)
schedule_delayed_work(&di->work, 0);
}
+static irqreturn_t bq27x00_chg_isr(int irq, void *dev) {
+
+ struct power_supply *ps = (struct power_supply*) dev;
+ wake_lock_timeout(&chg_wake_lock, msecs_to_jiffies(500));
+ dev_dbg(ps->dev, "%s: Updating battery status\n", __func__);
+ bq27x00_external_power_changed(ps);
+
+ return IRQ_HANDLED;
+}
+
static void __init set_properties_array(struct bq27x00_device_info *di,
enum power_supply_property *props, int num_props)
{
@@ -1393,6 +1409,25 @@ static int __init bq27x00_powersupply_init(struct bq27x00_device_info *di)
return ret;
}
+ wake_lock_init(&chg_wake_lock, WAKE_LOCK_SUSPEND, "chg_wake_lock");
+
+ if(di->irq) {
+ // If using an irq, disable poll interal
+ poll_interval = 0;
+ ret = request_irq(di->irq, bq27x00_chg_isr, IRQF_TRIGGER_RISING,
+ "bq27x00 chg", &di->bat);
+ if (ret) {
+ dev_err(di->dev, "failed to request irq: %d\n", di->irq);
+ return ret;
+ }
+
+ ret = enable_irq_wake(di->irq);
+ if (ret) {
+ dev_err(di->dev, "failed to enable irq: %d, as wake\n", di->irq);
+ return ret;
+ }
+ }
+
dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION);
bq27x00_update(di);
@@ -1414,6 +1449,10 @@ static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)
power_supply_unregister(&di->bat);
+ if(di->irq) {
+ free_irq(di->irq, di);
+ }
+
mutex_destroy(&di->lock);
}
@@ -1685,6 +1724,7 @@ static int __init bq27x00_battery_probe(struct i2c_client *client,
di->bus.blk_write = bq27xxx_write_i2c_blk;
di->dm_regs = NULL;
di->dm_regs_count = 0;
+ di->irq = client->irq;
if (di->chip == BQ27200)
regs = bq27200_regs;
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c
index a9caf043b0c..cdbf1a2b251 100644
--- a/drivers/rtc/rtc-tps65910.c
+++ b/drivers/rtc/rtc-tps65910.c
@@ -25,6 +25,9 @@
#include <linux/pm_runtime.h>
#include <linux/interrupt.h>
#include <linux/mfd/tps65910.h>
+#include <linux/wakelock.h>
+
+struct wake_lock rtc_wake_lock;
struct tps65910_rtc {
struct rtc_device *rtc;
@@ -197,6 +200,7 @@ static irqreturn_t tps65910_rtc_interrupt(int irq, void *rtc)
int ret;
u32 rtc_reg;
+ wake_lock_timeout(&rtc_wake_lock, msecs_to_jiffies(2000));
ret = regmap_read(tps->regmap, TPS65910_RTC_STATUS, &rtc_reg);
if (ret)
return IRQ_NONE;
@@ -285,6 +289,7 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, tps_rtc);
+ wake_lock_init(&rtc_wake_lock, WAKE_LOCK_SUSPEND, "rtc_wake_lock");
return 0;
}
diff --git a/include/linux/led-lm3530.h b/include/linux/led-lm3530.h
index 4b133479d6e..963ecb68002 100644
--- a/include/linux/led-lm3530.h
+++ b/include/linux/led-lm3530.h
@@ -60,6 +60,7 @@
enum lm3530_mode {
LM3530_BL_MODE_MANUAL = 0, /* "man" */
+ LM3530_BL_MODE_SIMPLE_MANUAL, /* "man" simple enable/disable */
LM3530_BL_MODE_ALS, /* "als" */
LM3530_BL_MODE_PWM, /* "pwm" */
};
@@ -93,6 +94,7 @@ struct lm3530_pwm_data {
* @als_vmin: als input voltage calibrated for max brightness in mV
* @als_vmax: als input voltage calibrated for min brightness in mV
* @brt_val: brightness value (0-127)
+ * @pwm_gpio: PWM control pin
* @pwm_data: PWM control functions (only valid when the mode is PWM)
*/
struct lm3530_platform_data {
@@ -115,6 +117,8 @@ struct lm3530_platform_data {
u8 brt_val;
+ int pwm_gpio;
+
struct lm3530_pwm_data pwm_data;
};