From 3ba3424669df90c827876ec107172f0caad886c1 Mon Sep 17 00:00:00 2001 From: Evan Wilson Date: Mon, 20 Jul 2015 18:15:40 -0700 Subject: Revert "HACK: Tricking significant motion to work off of the tap gesture interrupt" This reverts commit ecf02dbfdbd1caab5c79b2d3bff188a5360a9da4. Change-Id: I75dcbb82c9c50ea39ff2d4baddbe145a6c458e16 --- drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c | 73 ++++++++++--------------- drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c | 40 ++++---------- 2 files changed, 38 insertions(+), 75 deletions(-) diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c index b6eaa08ae83..72881512c1b 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c @@ -156,13 +156,8 @@ #define ST_LSM6DS3_GYRO_STD 6 /* CUSTOM VALUES FOR SIGNIFICANT MOTION SENSOR */ -/****** - * WARNING - * Evan: Switching Sig motion to use Tap interrupt - */ -#define ST_LSM6DS3_SIGN_MOTION_EN_ADDR 0x58 -#define ST_LSM6DS3_SIGN_MOTION_EN_MASK 0x02 -#define ST_LSM6DS3_SIGN_MOTION_DRDY_IRQ_MASK 0x40 +#define ST_LSM6DS3_SIGN_MOTION_EN_ADDR 0x19 +#define ST_LSM6DS3_SIGN_MOTION_EN_MASK 0x01 /* CUSTOM VALUES FOR STEP DETECTOR SENSOR */ #define ST_LSM6DS3_STEP_DETECTOR_DRDY_IRQ_MASK 0x80 @@ -850,7 +845,6 @@ EXPORT_SYMBOL(st_lsm6ds3_reconfigure_fifo); int st_lsm6ds3_set_drdy_irq(struct lsm6ds3_sensor_data *sdata, bool state) { - int err; u8 reg_addr, mask, value; if (state) @@ -890,18 +884,12 @@ 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 (sdata->cdata->sensors_enabled & - // (1 << ST_INDIO_DEV_STEP_DETECTOR)) - // return 0; - // The double tap needs to be enabled in-order for latched mode to work - err = st_lsm6ds3_write_data_with_mask(sdata->cdata, - ST_LSM6DS3_MD1_ADDR, - 0x08, - ST_LSM6DS3_EN_BIT, true); - if (err < 0) - return err; - reg_addr = ST_LSM6DS3_MD1_ADDR; - mask = ST_LSM6DS3_SIGN_MOTION_DRDY_IRQ_MASK; + if (sdata->cdata->sensors_enabled & + (1 << ST_INDIO_DEV_STEP_DETECTOR)) + return 0; + + reg_addr = ST_LSM6DS3_INT1_ADDR; + mask = ST_LSM6DS3_STEP_DETECTOR_DRDY_IRQ_MASK; break; case ST_INDIO_DEV_STEP_COUNTER: reg_addr = ST_LSM6DS3_INT2_ADDR; @@ -1087,31 +1075,26 @@ static int st_lsm6ds3_enable_sensors(struct lsm6ds3_sensor_data *sdata) if (err < 0) return err; -// if ((sdata->cdata->sensors_enabled & ~(1 << sdata->sindex)) & -// ST_LSM6DS3_PEDOMETER_DEPENDENCY) { -// err = st_lsm6ds3_write_data_with_mask(sdata->cdata, -// ST_LSM6DS3_PEDOMETER_EN_ADDR, -// ST_LSM6DS3_PEDOMETER_EN_MASK, -// ST_LSM6DS3_DIS_BIT, true); -// if (err < 0) -// return err; -// -// err = st_lsm6ds3_write_data_with_mask(sdata->cdata, -// ST_LSM6DS3_PEDOMETER_EN_ADDR, -// ST_LSM6DS3_PEDOMETER_EN_MASK, -// ST_LSM6DS3_EN_BIT, true); -// if (err < 0) -// return err; -// } else { -// err = st_lsm6ds3_enable_pedometer(sdata, true); -// if (err < 0) -// return err; -// } - - // This sets the TAP threshold - err = st_lsm6ds3_write_data_with_mask(sdata->cdata, 0x59, 0x1F, 0x04, true); - if (err < 0) - return err; + if ((sdata->cdata->sensors_enabled & ~(1 << sdata->sindex)) & + ST_LSM6DS3_PEDOMETER_DEPENDENCY) { + err = st_lsm6ds3_write_data_with_mask(sdata->cdata, + ST_LSM6DS3_PEDOMETER_EN_ADDR, + ST_LSM6DS3_PEDOMETER_EN_MASK, + ST_LSM6DS3_DIS_BIT, true); + if (err < 0) + return err; + + err = st_lsm6ds3_write_data_with_mask(sdata->cdata, + ST_LSM6DS3_PEDOMETER_EN_ADDR, + ST_LSM6DS3_PEDOMETER_EN_MASK, + ST_LSM6DS3_EN_BIT, true); + if (err < 0) + return err; + } else { + err = st_lsm6ds3_enable_pedometer(sdata, true); + if (err < 0) + return err; + } break; case ST_INDIO_DEV_STEP_COUNTER: diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c index f5108a7526e..fb739c883d4 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c @@ -20,9 +20,7 @@ #define ST_LSM6DS3_SRC_FUNC_ADDR 0x53 #define ST_LSM6DS3_FIFO_DATA_AVL_ADDR 0x3b -#define ST_LSM6DS3_TAP_FUNC_ADDR 0x1C -#define ST_LSM6DS3_SRC_SIGN_MOTION_DATA_AVL 0x40 #define ST_LSM6DS3_SRC_STEP_DETECTOR_DATA_AVL 0x10 #define ST_LSM6DS3_SRC_TILT_DATA_AVL 0x20 #define ST_LSM6DS3_SRC_STEP_COUNTER_DATA_AVL 0x80 @@ -53,7 +51,7 @@ irqreturn_t st_lsm6ds3_save_timestamp(int irq, void *private) static void st_lsm6ds3_irq_management(struct work_struct *data_work) { struct lsm6ds3_data *cdata; - u8 src_value = 0x00, src_fifo = 0x00, tap_value = 0x00, tap_cfg = 0x00, int1_cfg = 0x00, tap_thresh = 0x00; + u8 src_value = 0x00, src_fifo = 0x00; cdata = container_of((struct work_struct *)data_work, struct lsm6ds3_data, data_work); @@ -61,14 +59,6 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) cdata->tf->read(cdata, ST_LSM6DS3_SRC_FUNC_ADDR, 1, &src_value, true); cdata->tf->read(cdata, ST_LSM6DS3_FIFO_DATA_AVL_ADDR, 1, &src_fifo, true); - cdata->tf->read(cdata, ST_LSM6DS3_TAP_FUNC_ADDR, 1, - &tap_value, true); - cdata->tf->read(cdata, 0x58, 1, - &tap_cfg, true); - cdata->tf->read(cdata, 0x5E, 1, - &int1_cfg, true); - cdata->tf->read(cdata, 0x59, 1, - &tap_thresh, true); if (src_fifo & ST_LSM6DS3_FIFO_DATA_AVL) { if (src_fifo & ST_LSM6DS3_FIFO_DATA_OVR) { @@ -86,27 +76,17 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), cdata->timestamp); -// if (cdata->sign_motion_event_ready) { -// iio_push_event(cdata->indio_dev[ -// ST_INDIO_DEV_SIGN_MOTION], -// IIO_UNMOD_EVENT_CODE(IIO_SIGN_MOTION, -// 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), -// cdata->timestamp); -// -// cdata->sign_motion_event_ready = false; -// } - } + if (cdata->sign_motion_event_ready) { + iio_push_event(cdata->indio_dev[ + ST_INDIO_DEV_SIGN_MOTION], + IIO_UNMOD_EVENT_CODE(IIO_SIGN_MOTION, + 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), + cdata->timestamp); - if (cdata->sign_motion_event_ready && - (tap_value & ST_LSM6DS3_SRC_SIGN_MOTION_DATA_AVL)) { - printk("Firing Sig motion event. Tap value: %x, Tap cfg: %x, Int cfg: %x, Tap thresh: %x\n", tap_value, tap_cfg, int1_cfg, tap_thresh); - iio_push_event(cdata->indio_dev[ - ST_INDIO_DEV_SIGN_MOTION], - IIO_UNMOD_EVENT_CODE(IIO_SIGN_MOTION, - 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - cdata->timestamp); - cdata->sign_motion_event_ready = false; + cdata->sign_motion_event_ready = false; + } } + if (src_value & ST_LSM6DS3_SRC_STEP_COUNTER_DATA_AVL) { iio_trigger_poll_chained( cdata->trig[ST_INDIO_DEV_STEP_COUNTER], 0); -- cgit v1.2.3-70-g09d2 From 10eaae2610ede7622cca6e9d348ec55a38316611 Mon Sep 17 00:00:00 2001 From: Evan Wilson Date: Mon, 20 Jul 2015 18:16:22 -0700 Subject: Adding in MindTribe changes from 7/17/2015 Change-Id: I8e8f5feb3380578f8ab6e7411c3658eb412e73c6 --- drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h | 18 +- drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c | 20 +- drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c | 258 +++++++++++++++++++++++- drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c | 89 +++++++- 4 files changed, 363 insertions(+), 22 deletions(-) diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h index 78fbf76f4c2..479b9188273 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h @@ -13,7 +13,7 @@ #include #include - +#include #ifdef CONFIG_ST_LSM6DS3_IIO_MASTER_SUPPORT #include #endif /* CONFIG_ST_LSM6DS3_IIO_MASTER_SUPPORT */ @@ -120,11 +120,27 @@ struct st_lsm6ds3_transfer_buffer { u8 tx_buf[ST_LSM6DS3_TX_MAX_LENGTH] ____cacheline_aligned; }; +enum +{ + LSM6DS3_WAKEUP_NONE = 0, + LSM6DS3_WAKEUP_TAP = 1, + LSM6DS3_WAKEUP_6D = 2, + LSM6DS3_WAKEUP_OTHER = 4 +}; + struct lsm6ds3_data { const char *name; bool reset_steps; bool sign_motion_event_ready; + int last_wakeup_source; + int wake_lock_initialized; + struct wake_lock wlock; + u8 first_irq_from_resume; + u8 reg_read; +#define SIXD_MASK_VALID_BITS (0x3f) + u8 sixd_mask; + u8 int1_save; u8 *fifo_data; u8 sensors_enabled; diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c index 8a7cc5176c2..138868dd5ba 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c @@ -7,6 +7,7 @@ * * Licensed under the GPL-2. */ +#define DEBUG #include #include @@ -152,20 +153,23 @@ void st_lsm6ds3_read_fifo(struct lsm6ds3_data *cdata, bool check_fifo_len) u16 data_remaining, data_to_read; #endif /* CONFIG_ST_LSM6DS3_IIO_LIMIT_FIFO */ u16 read_len = cdata->fifo_threshold, byte_in_pattern; - - if (!cdata->fifo_data) + if (!cdata->fifo_data){ + dev_err(cdata->dev, "No cdata->fifo_data! can't use fifo"); return; - + } if (check_fifo_len) { err = cdata->tf->read(cdata, ST_LSM6DS3_FIFO_DIFF_L, 2, (u8 *)&read_len, true); - if (err < 0) + if (err < 0){ + dev_dbg(cdata->dev, "could not read the fifo length. err: %i", err); return; + } if (read_len & ST_LSM6DS3_FIFO_DATA_OVR_2REGS) { - dev_err(cdata->dev, - "data fifo overrun, failed to read it.\n"); - return; + dev_dbg(cdata->dev, + "DATA overrun, setting read_len to threshold\n"); + read_len = cdata->fifo_threshold; + //return; } read_len &= ST_LSM6DS3_FIFO_DIFF_MASK; @@ -184,7 +188,7 @@ void st_lsm6ds3_read_fifo(struct lsm6ds3_data *cdata, bool check_fifo_len) #endif /* CONFIG_ST_LSM6DS3_IIO_MASTER_SUPPORT */ read_len = (read_len / byte_in_pattern) * byte_in_pattern; - + dev_dbg(cdata->dev, "Fifo avail: %i thresh: %i", read_len, cdata->fifo_threshold); if (read_len > cdata->fifo_threshold) read_len = cdata->fifo_threshold; } diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c index 72881512c1b..bbb024e3a4d 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c @@ -25,7 +25,7 @@ #include #include #include - +#include #include #include "st_lsm6ds3.h" @@ -99,7 +99,7 @@ #define ST_LSM6DS3_FIFO_THRESHOLD_IRQ_MASK 0x08 #define ST_LSM6DS3_FIFO_ODR_ADDR 0x0a #define ST_LSM6DS3_FIFO_ODR_MASK 0x78 -#define ST_LSM6DS3_FIFO_ODR_MAX 0x08 +#define ST_LSM6DS3_FIFO_ODR_MAX 0x04 // prev max:0x08 #define ST_LSM6DS3_FIFO_ODR_OFF 0x00 #define ST_LSM6DS3_FIFO_DECIMATOR_ADDR 0x08 #define ST_LSM6DS3_FIFO_ACCEL_DECIMATOR_MASK 0x07 @@ -176,6 +176,12 @@ #define ST_LSM6DS3_TILT_EN_MASK 0x20 #define ST_LSM6DS3_TILT_DRDY_IRQ_MASK 0x02 +/* 6d Constants */ + + +#define ST_LSM6DS3_6D_MD1_INT_MASK 0x04 +#define ST_LSM6DS3_SINGTAP_MD1_INT_MASK 0x40 + #define ST_LSM6DS3_ACCEL_SUFFIX_NAME "accel" #define ST_LSM6DS3_GYRO_SUFFIX_NAME "gyro" #define ST_LSM6DS3_STEP_COUNTER_SUFFIX_NAME "step_c" @@ -234,7 +240,8 @@ static struct st_lsm6ds3_odr_table { .mask[ST_INDIO_DEV_ACCEL] = ST_LSM6DS3_ACCEL_ODR_MASK, .addr[ST_INDIO_DEV_GYRO] = ST_LSM6DS3_GYRO_ODR_ADDR, .mask[ST_INDIO_DEV_GYRO] = ST_LSM6DS3_GYRO_ODR_MASK, - .odr_avl[0] = { .hz = 26, .value = ST_LSM6DS3_ODR_26HZ_VAL }, + //hack , remove + .odr_avl[0] = { .hz = 416, .value = ST_LSM6DS3_ODR_416HZ_VAL }, .odr_avl[1] = { .hz = 52, .value = ST_LSM6DS3_ODR_52HZ_VAL }, .odr_avl[2] = { .hz = 104, .value = ST_LSM6DS3_ODR_104HZ_VAL }, .odr_avl[3] = { .hz = 208, .value = ST_LSM6DS3_ODR_208HZ_VAL }, @@ -658,6 +665,7 @@ int st_lsm6ds3_set_fifo_decimators_and_threshold(struct lsm6ds3_data *cdata) (sdata_accel->c_odr / min_odr); num_pattern_accel = MAX(fifo_len_accel / cdata->accel_samples_in_pattern, 1); + //TODO: this needs to reflect fifo odr rates and not c_odr cdata->accel_deltatime = (1000000000ULL / sdata_accel->c_odr); accel_decimator = max_odr / sdata_accel->c_odr; } else @@ -775,6 +783,7 @@ int st_lsm6ds3_set_fifo_decimators_and_threshold(struct lsm6ds3_data *cdata) if (fifo_len > 0) { fifo_threshold = fifo_len / 2; + dev_info(cdata->dev,"setting FIFO length/threshold: 0x%x 0x%x ", fifo_len, fifo_threshold); err = cdata->tf->write(cdata, ST_LSM6DS3_FIFO_THR_L_ADDR, 1, (u8 *)&fifo_threshold, true); @@ -885,11 +894,35 @@ int st_lsm6ds3_set_drdy_irq(struct lsm6ds3_sensor_data *sdata, bool state) break; case ST_INDIO_DEV_SIGN_MOTION: if (sdata->cdata->sensors_enabled & - (1 << ST_INDIO_DEV_STEP_DETECTOR)) + (1 << ST_INDIO_DEV_STEP_DETECTOR)){ + dev_err(sdata->cdata->dev, "can't set up significant motion irq, step detector enabled"); return 0; + } + dev_info(sdata->cdata->dev,"--sig mot irq setup: %i", value); + if(value == 0 ){ + //need this so that sig motion can reregister before we sleep, + //otherwise we'll sleep and never wake up + wake_lock_timeout(&sdata->cdata->wlock, msecs_to_jiffies(1000)); + dev_err(sdata->cdata->dev, "IRQ disabled for md1 sig motion"); + //dump_stack(); + + } +#if 0 reg_addr = ST_LSM6DS3_INT1_ADDR; mask = ST_LSM6DS3_STEP_DETECTOR_DRDY_IRQ_MASK; + st_lsm6ds3_write_data_with_mask(sdata->cdata, + reg_addr, mask, value, true); +#endif +//TODO: move this to init since we don't need to set up the parameters every time + reg_addr = ST_LSM6DS3_MD1_ADDR; + mask = ST_LSM6DS3_6D_MD1_INT_MASK; + st_lsm6ds3_write_data_with_mask(sdata->cdata, + reg_addr, mask, value, true); + + reg_addr = ST_LSM6DS3_MD1_ADDR; + mask = ST_LSM6DS3_SINGTAP_MD1_INT_MASK; + //written at end of func break; case ST_INDIO_DEV_STEP_COUNTER: reg_addr = ST_LSM6DS3_INT2_ADDR; @@ -899,7 +932,7 @@ int st_lsm6ds3_set_drdy_irq(struct lsm6ds3_sensor_data *sdata, bool state) if (sdata->cdata->sensors_enabled & (1 << ST_INDIO_DEV_SIGN_MOTION)) return 0; - + dev_info(sdata->cdata->dev, "setting up STEP count irq"); reg_addr = ST_LSM6DS3_INT1_ADDR; mask = ST_LSM6DS3_STEP_DETECTOR_DRDY_IRQ_MASK; break; @@ -1405,6 +1438,7 @@ static int st_lsm6ds3_init_sensor(struct lsm6ds3_data *cdata) { int err, i; u8 default_reg_value = 0; + u8 regval = 0; struct lsm6ds3_sensor_data *sdata; mutex_init(&cdata->tb.buf_lock); @@ -1505,11 +1539,55 @@ static int st_lsm6ds3_init_sensor(struct lsm6ds3_data *cdata) ST_LSM6DS3_DIS_BIT, false); if (err < 0) goto st_lsm6ds3_init_sensor_mutex_unlock; +//set up tap stuff +#define ST_LSM6DS3_TAP_CFG_ADDR 0x58 +#define ST_LSM6DS3_TAP_CFG_XYZ_MASK (0xE) + //1 is for latch enable +#define ST_LSM6DS3_TAP_THS_6D_ADDR 0x59 +#define ST_LSM6DS3_INT_DUR2_ADDR 0x5A +#define ST_LSM6DS3_CTRL8_ADDR 0x17 +#define ST_LSM6DS3_CTRL8_LPF_ON_6D 0x01 +#define ST_LSM6DS3_CTRL8_LPF_ON_ACCEL 0x80 + +#define ST_LSM6DS3_CTRL4C_ADDR 0x13 + + regval = 0x50;//tap threshold + err = sdata->cdata->tf->write(sdata->cdata, + ST_LSM6DS3_TAP_THS_6D_ADDR, + 1, ®val, false); + regval = 0x6; //quiet and shock times + err = sdata->cdata->tf->write(sdata->cdata, + ST_LSM6DS3_INT_DUR2_ADDR, + 1, ®val, false); + + 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, ®val, false); + + regval = ST_LSM6DS3_CTRL8_LPF_ON_6D | ST_LSM6DS3_CTRL8_LPF_ON_ACCEL; + err = sdata->cdata->tf->write(sdata->cdata, + ST_LSM6DS3_CTRL8_ADDR , + 1, ®val, false); + + regval = 1;//todo fix this because it overwrites int2_on_int1 bit + err = sdata->cdata->tf->write(sdata->cdata, + ST_LSM6DS3_CTRL4C_ADDR , + 1, ®val, false); + + if (err < 0) + goto st_lsm6ds3_init_sensor_mutex_unlock; + + + + // mutex_unlock(&cdata->bank_registers_lock); sdata->c_odr = 0; + return 0; st_lsm6ds3_init_sensor_mutex_unlock: @@ -1773,6 +1851,89 @@ ssize_t st_lsm6ds3_sysfs_flush_fifo(struct device *dev, return size; } +ssize_t st_lsm6ds3_sysfs_get_irq_src(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lsm6ds3_sensor_data *sdata = iio_priv(dev_get_drvdata(dev)); + ssize_t ret = sprintf(buf, "%d\n", sdata->cdata->last_wakeup_source); + sdata->cdata->last_wakeup_source = 0; //clear flags + return ret; +} + + +static ssize_t st_lsm6ds3_sysfs_write_reg(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int ret; + struct lsm6ds3_sensor_data *sdata = iio_priv(dev_get_drvdata(dev)); + uint32_t waddr, wval; + ret = sscanf(buf, "%i %i", &waddr, &wval); + dev_info(sdata->cdata->dev, "read: 0x%x 0x%x", waddr, wval); + if(ret != 2){ + dev_err(sdata->cdata->dev,"error, write_reg usage: addr val"); + return -EINVAL; + } + + sdata->cdata->tf->write(sdata->cdata, waddr, 1, (u8 *)&wval, true); + + return size; +} + +static ssize_t st_lsm6ds3_sysfs_read_reg_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int ret ; + struct lsm6ds3_sensor_data *sdata = iio_priv(dev_get_drvdata(dev)); + uint32_t waddr, wval; + ret = sscanf(buf, "%i", &waddr); + dev_info(dev, "read: 0x%x ", waddr); + if(ret != 1){ + dev_err(sdata->cdata->dev,"error, read_reg usage: addr "); + return -EINVAL; + } + + sdata->cdata->tf->read(sdata->cdata, waddr, 1, &sdata->cdata->reg_read, true); + + return size; +} + + +ssize_t st_lsm6ds3_sysfs_read_reg_get(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lsm6ds3_sensor_data *sdata = iio_priv(dev_get_drvdata(dev)); + ssize_t ret = sprintf(buf, "%d\n", sdata->cdata->reg_read); + return ret; +} + +ssize_t st_lsm6ds3_sysfs_sixd_wake_mask_get(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lsm6ds3_sensor_data *sdata = iio_priv(dev_get_drvdata(dev)); + ssize_t ret = sprintf(buf, "0x%02x\n", sdata->cdata->sixd_mask); + return ret; +} + + +static ssize_t st_lsm6ds3_sysfs_sixd_wake_mask_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int ret ; + struct lsm6ds3_sensor_data *sdata = iio_priv(dev_get_drvdata(dev)); + uint32_t maskval; + ret = sscanf(buf, "%i", &maskval); + dev_info(sdata->cdata->dev, "read: 0x%x ", maskval); + if(ret != 1 || maskval ){ + dev_info(sdata->cdata->dev, "read: 0x%x ", maskval); + dev_err(sdata->cdata->dev,"error, sixd_mask usage: mask sig mot events from"); + dev_err(sdata->cdata->dev,"ZH | ZL | YH | YL | XH | XL \n"); + return -EINVAL; + } + + sdata->cdata->sixd_mask = maskval & SIXD_MASK_VALID_BITS; + + return size; +} static ST_LSM6DS3_DEV_ATTR_SAMP_FREQ(); static ST_LSM6DS3_DEV_ATTR_SAMP_FREQ_AVAIL(); static ST_LSM6DS3_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available); @@ -1795,6 +1956,23 @@ static IIO_DEVICE_ATTR(self_test, S_IWUSR | S_IRUGO, st_lsm6ds3_sysfs_get_selftest_status, st_lsm6ds3_sysfs_set_selftest_status, 0); +static IIO_DEVICE_ATTR(irq_source, S_IRUGO, + st_lsm6ds3_sysfs_get_irq_src, + NULL, 0); + + +static IIO_DEVICE_ATTR(write_reg, S_IWUSR, + NULL, st_lsm6ds3_sysfs_write_reg, 0); + + +static IIO_DEVICE_ATTR(read_reg, S_IRUGO | S_IWUSR, + st_lsm6ds3_sysfs_read_reg_get, + st_lsm6ds3_sysfs_read_reg_set, 0); + +static IIO_DEVICE_ATTR(sixd_wake_mask, S_IRUGO | S_IWUSR, + st_lsm6ds3_sysfs_sixd_wake_mask_get, + st_lsm6ds3_sysfs_sixd_wake_mask_set, 0); + static struct attribute *st_lsm6ds3_accel_attributes[] = { &iio_dev_attr_sampling_frequency_available.dev_attr.attr, &iio_dev_attr_in_accel_scale_available.dev_attr.attr, @@ -1803,6 +1981,10 @@ static struct attribute *st_lsm6ds3_accel_attributes[] = { &iio_dev_attr_self_test.dev_attr.attr, &iio_dev_attr_hw_fifo_lenght.dev_attr.attr, &iio_dev_attr_flush.dev_attr.attr, + &iio_dev_attr_irq_source.dev_attr.attr, + &iio_dev_attr_write_reg.dev_attr.attr, + &iio_dev_attr_read_reg.dev_attr.attr, + &iio_dev_attr_sixd_wake_mask.dev_attr.attr, NULL, }; @@ -1912,6 +2094,7 @@ int st_lsm6ds3_common_probe(struct lsm6ds3_data *cdata, int irq) mutex_init(&cdata->bank_registers_lock); mutex_init(&cdata->fifo_lock); + wake_lock_init(&cdata->wlock, WAKE_LOCK_SUSPEND, "st_lsm6ds3_kdriv_lock"); #ifdef CONFIG_ST_LSM6DS3_IIO_MASTER_SUPPORT mutex_init(&cdata->passthrough_lock); @@ -1952,6 +2135,8 @@ int st_lsm6ds3_common_probe(struct lsm6ds3_data *cdata, int irq) dev_info(cdata->dev, "driver use DRDY int pin 1\n"); } + cdata->sixd_mask = SIXD_MASK_VALID_BITS; + cdata->indio_dev[ST_INDIO_DEV_ACCEL]->name = kasprintf(GFP_KERNEL, "%s_%s", cdata->name, ST_LSM6DS3_ACCEL_SUFFIX_NAME); @@ -2077,27 +2262,78 @@ int st_lsm6ds3_common_suspend(struct lsm6ds3_data *cdata) int err, i; u8 tmp_sensors_enabled; struct lsm6ds3_sensor_data *sdata; + u8 reg_value; tmp_sensors_enabled = cdata->sensors_enabled; + dev_info(cdata->dev, "entering suspend"); for (i = 0; i < ST_INDIO_DEV_NUM; i++) { + sdata = iio_priv(cdata->indio_dev[i]); if ((i == ST_INDIO_DEV_SIGN_MOTION) || (i == ST_INDIO_DEV_TILT)) continue; + if(i == ST_INDIO_DEV_ACCEL){ + //stop the fifo + err = st_lsm6ds3_set_drdy_irq(sdata, false); + cdata->int1_save = 1; + continue; //do not disable + } - sdata = iio_priv(cdata->indio_dev[i]); err = st_lsm6ds3_set_enable(sdata, false); + //todo: see if this is good + err = st_lsm6ds3_set_drdy_irq(sdata, false); if (err < 0) return err; } cdata->sensors_enabled = tmp_sensors_enabled; + #endif /* CONFIG_ST_LSM6DS3_IIO_SENSORS_WAKEUP */ if (cdata->sensors_enabled & ST_LSM6DS3_WAKE_UP_SENSORS) { if (device_may_wakeup(cdata->dev)) enable_irq_wake(cdata->irq); } + err = cdata->tf->read(cdata, + ST_LSM6DS3_MD1_ADDR, 1, ®_value, true); + dev_info(cdata->dev, "before suspend md1: %x, err:%i", reg_value, err); + dev_info(cdata->dev, "manually setting to 0x44"); + reg_value = 0x44; + err = cdata->tf->write(cdata, + ST_LSM6DS3_MD1_ADDR, 1, ®_value, true); + err = cdata->tf->read(cdata, + ST_LSM6DS3_MD1_ADDR, 1, ®_value, true); + dev_info(cdata->dev, "before suspend md1: %x, err:%i", reg_value, err); + + err = cdata->tf->read(cdata, + 0xd, 1, ®_value, true); + dev_info(cdata->dev, "before suspend int1: %x err:%i", reg_value, err); + err = cdata->tf->read(cdata, + 0x58, 1, ®_value, true); + dev_info(cdata->dev, "before suspend 0x58 tap enable: %x err:%i", reg_value, err); + err = cdata->tf->read(cdata, + 0x10, 1, ®_value, true); + dev_info(cdata->dev, "ctrl1_xl: %x err:%i", reg_value, err); + + err = cdata->tf->read(cdata, + 0xa, 1, ®_value, true); + dev_info(cdata->dev, "before suspend 0xA fifo mode: %x err:%i", reg_value, err); + + err = cdata->tf->read(cdata, + 0x13, 1, ®_value, true); + dev_info(cdata->dev, "before suspend 0x13 ctrl4_c : %x err:%i", reg_value, err); + + err = cdata->tf->read(cdata, + 0x06, 1, ®_value, true); + dev_info(cdata->dev, "before suspend 0x6 fifo_fth : %x err:%i", reg_value, err); + + + + reg_value = 624; //set fifo to 1 second of data (104hz fifo) + err = cdata->tf->write(cdata, + ST_LSM6DS3_FIFO_THR_L_ADDR, 1, ®_value, true); + + cdata->first_irq_from_resume = 1; return 0; } EXPORT_SYMBOL(st_lsm6ds3_common_suspend); @@ -2107,6 +2343,7 @@ int st_lsm6ds3_common_resume(struct lsm6ds3_data *cdata) #ifndef CONFIG_ST_LSM6DS3_IIO_SENSORS_WAKEUP int err, i; struct lsm6ds3_sensor_data *sdata; + u8 reg_value; for (i = 0; i < ST_INDIO_DEV_NUM; i++) { if ((i == ST_INDIO_DEV_SIGN_MOTION) || (i == ST_INDIO_DEV_TILT)) @@ -2114,6 +2351,12 @@ int st_lsm6ds3_common_resume(struct lsm6ds3_data *cdata) sdata = iio_priv(cdata->indio_dev[i]); + 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; + } + if ((1 << sdata->sindex) & cdata->sensors_enabled) { err = st_lsm6ds3_set_enable(sdata, true); if (err < 0) @@ -2126,6 +2369,9 @@ int st_lsm6ds3_common_resume(struct lsm6ds3_data *cdata) if (device_may_wakeup(cdata->dev)) disable_irq_wake(cdata->irq); } + reg_value = 624/8; //set fifo to 1 second of data (104hz fifo) + err = cdata->tf->write(cdata, + ST_LSM6DS3_FIFO_THR_L_ADDR, 1, ®_value, true); return 0; } diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c index fb739c883d4..ccb215c20d0 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c @@ -8,13 +8,17 @@ * Licensed under the GPL-2. */ +#define DEBUG //TODO: remove + #include +#include #include #include #include #include #include #include +#include #include "st_lsm6ds3.h" @@ -27,6 +31,15 @@ #define ST_LSM6DS3_FIFO_DATA_AVL 0x80 #define ST_LSM6DS3_FIFO_DATA_OVR 0x40 +#define ST_LSM6DS3_TAP_SRC_ADDR 0x1c +#define ST_LSM6DS3_TAP_SRC_DETECTED_MASK (1<<6) +#define ST_LSM6DS3_TAP_SRC_SINGLE_TAP_MASK (1<<5) +#define ST_LSM6DS3_TAP_SRC_Z_AXIS_MASK (1<<0) + +#define ST_LSM6DS3_6D_SRC_ADDR 0x1d + + + static struct workqueue_struct *st_lsm6ds3_wq; void st_lsm6ds3_flush_works() @@ -41,6 +54,7 @@ irqreturn_t st_lsm6ds3_save_timestamp(int irq, void *private) get_monotonic_boottime(&ts); cdata->timestamp = timespec_to_ns(&ts); + cdata->accel_timestamp = cdata->timestamp; queue_work(st_lsm6ds3_wq, &cdata->data_work); disable_irq_nosync(irq); @@ -51,23 +65,79 @@ irqreturn_t st_lsm6ds3_save_timestamp(int irq, void *private) static void st_lsm6ds3_irq_management(struct work_struct *data_work) { struct lsm6ds3_data *cdata; + u8 d6d_src_reg, tap_src_reg; u8 src_value = 0x00, src_fifo = 0x00; + u8 d6d_event = 0; + u8 tap_event = 0; + //u8 read_buff[2] = {0}; + cdata = container_of((struct work_struct *)data_work, struct lsm6ds3_data, data_work); + if(!wake_lock_active(&cdata->wlock)) + wake_lock(&cdata->wlock); + + //cdata->tf->read(cdata, ST_LSM6DS3_TAP_SRC_ADDR, 2, &read_buff[0], true); + //tap_src_reg = read_buff[0]; + //d6d_src_reg = read_buff[1]; + 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); cdata->tf->read(cdata, ST_LSM6DS3_FIFO_DATA_AVL_ADDR, 1, &src_fifo, true); + dev_dbg(cdata->dev, "ST irq start :src_value, 6d, tap:%x %x %x",src_value, d6d_src_reg, tap_src_reg); + + if(d6d_src_reg & (1<<6)){ + dev_info(cdata->dev, "D6D IRQ"); + if(cdata->sixd_mask & d6d_src_reg){ + d6d_event = 1; + cdata->last_wakeup_source |= LSM6DS3_WAKEUP_6D; + } + else{ + dev_info(cdata->dev, "ignoring 6d interrupt, wrong axis. mask: 0x%x", cdata->sixd_mask); + } + + } + if(tap_src_reg & ST_LSM6DS3_TAP_SRC_DETECTED_MASK){ + dev_info(cdata->dev, "TAP IRQ"); + if(tap_src_reg & (ST_LSM6DS3_TAP_SRC_SINGLE_TAP_MASK | ST_LSM6DS3_TAP_SRC_Z_AXIS_MASK)){ + tap_event = 1; + cdata->last_wakeup_source |= LSM6DS3_WAKEUP_TAP; + dev_info(cdata->dev, "Valid Tap"); + } + else { + dev_info(cdata->dev, "Ignoring tap"); + } + } + if(cdata->first_irq_from_resume){ + 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"); + tap_event = 1; + cdata->last_wakeup_source |= LSM6DS3_WAKEUP_TAP; + dev_info(cdata->dev, "Valid Tap from sleep"); + } + } + if (src_fifo & ST_LSM6DS3_FIFO_DATA_AVL) { - if (src_fifo & ST_LSM6DS3_FIFO_DATA_OVR) { - st_lsm6ds3_set_fifo_mode(cdata, BYPASS); - st_lsm6ds3_set_fifo_mode(cdata, CONTINUOS); - dev_err(cdata->dev, - "data fifo overrun, reduce fifo size.\n"); - } else - st_lsm6ds3_read_fifo(cdata, false); + dev_dbg(cdata->dev, "Fifo data available"); + st_lsm6ds3_read_fifo(cdata, true); + } +//significant motion event processing + if(d6d_event || tap_event){ + dev_info(cdata->dev, "Sending sig mot event"); + wake_lock_timeout(&cdata->wlock,msecs_to_jiffies(500)); + if (cdata->sign_motion_event_ready) { + iio_push_event(cdata->indio_dev[ + ST_INDIO_DEV_SIGN_MOTION], + IIO_UNMOD_EVENT_CODE(IIO_SIGN_MOTION, + 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), + cdata->accel_timestamp); + + cdata->sign_motion_event_ready = false; + } } if (src_value & ST_LSM6DS3_SRC_STEP_DETECTOR_DATA_AVL) { @@ -77,6 +147,7 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) cdata->timestamp); if (cdata->sign_motion_event_ready) { + dev_info(cdata->dev, "significant motion irq, pushing event (disable this?)"); iio_push_event(cdata->indio_dev[ ST_INDIO_DEV_SIGN_MOTION], IIO_UNMOD_EVENT_CODE(IIO_SIGN_MOTION, @@ -100,6 +171,10 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) } enable_irq(cdata->irq); + if(wake_lock_active(&cdata->wlock)) + wake_unlock(&cdata->wlock); + + cdata->first_irq_from_resume = 0; return; } -- cgit v1.2.3-70-g09d2 From 9db30827582bea855119fd4b707dae1e0e88f7ce Mon Sep 17 00:00:00 2001 From: mattis fjallstrom Date: Fri, 17 Jul 2015 18:05:58 -0700 Subject: Microphone driver updates, from Vadym Change-Id: I0aa136675b41918cd176a55da887128180a07163 --- sound/soc/omap/omap3h1.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/sound/soc/omap/omap3h1.c b/sound/soc/omap/omap3h1.c index 69d4b1abc06..f61949b295e 100644 --- a/sound/soc/omap/omap3h1.c +++ b/sound/soc/omap/omap3h1.c @@ -24,6 +24,8 @@ #define DEBUG #include +#include +#include #include #include #include @@ -36,6 +38,10 @@ #include "omap-mcbsp.h" +static struct clk *per_96m_fck; +static unsigned long rate; +static int mic_gpio_enable; + static int omap3h1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -50,7 +56,7 @@ static int omap3h1_hw_params(struct snd_pcm_substream *substream, // pr_info("ASoc OMAP3H1: setting system clock to: %d", freq); ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_FCLK, - 96000000, SND_SOC_CLOCK_OUT); + rate, SND_SOC_CLOCK_OUT); if (ret < 0) { printk(KERN_ERR "can't set DMIC cpu system clock\n"); return ret; @@ -68,8 +74,22 @@ static int omap3h1_hw_params(struct snd_pcm_substream *substream, return 0; } +static int omap3h1_startup(struct snd_pcm_substream *substream) +{ + gpio_set_value(mic_gpio_enable, 1); + return clk_enable(per_96m_fck); +} + +static void omap3h1_shutdown(struct snd_pcm_substream *substream) +{ + gpio_set_value(mic_gpio_enable, 0); + clk_disable(per_96m_fck); +} + static struct snd_soc_ops omap3h1_ops = { .hw_params = omap3h1_hw_params, + .startup = omap3h1_startup, + .shutdown = omap3h1_shutdown, }; //static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = { @@ -111,6 +131,7 @@ static int omap3h1_card_probe(struct platform_device *pdev) struct device_node *node = pdev->dev.of_node; struct snd_soc_card *card = &snd_soc_omap3h1; int ret = 0; + int gpio; #ifdef CONFIG_OF if (node) { @@ -128,6 +149,16 @@ static int omap3h1_card_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Missing node\n"); return -ENODEV; } + + gpio = of_get_named_gpio(node, "olio,mic_enable", 0); + ret = (gpio < 0) ? -ENODEV : gpio_request(gpio, "mic_enable"); + if (ret) { + dev_err(&pdev->dev, "GPIO request error gpio=%d err=%d\n", gpio, ret); + return ret; + } + gpio_direction_output(gpio, 0); + mic_gpio_enable = gpio; + #endif card->dev = &pdev->dev; @@ -140,12 +171,21 @@ static int omap3h1_card_probe(struct platform_device *pdev) return ret; } + per_96m_fck = clk_get(&pdev->dev, "per_96m_fck"); + if (IS_ERR(per_96m_fck)) { + dev_err(&pdev->dev, "could not get per_96m_fck clock\n"); + return PTR_ERR(per_96m_fck); + } + + rate = clk_get_rate(per_96m_fck); + return 0; } static int omap3h1_card_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); + gpio_free(mic_gpio_enable); snd_soc_unregister_card(card); return 0; @@ -196,7 +236,7 @@ static struct platform_driver omap3h1_driver = { .driver = { .name = "omap-soc-omap3h1", .of_match_table = of_match_ptr(omap_soc_h1_of_match), - .pm = &omap3h1_sound_pm_ops, + .pm = &snd_soc_pm_ops, }, .probe = omap3h1_card_probe, .remove = omap3h1_card_remove, -- cgit v1.2.3-70-g09d2 From 0597c8f6cf15239f82dfaf0a645581f8c7cbaab3 Mon Sep 17 00:00:00 2001 From: mattis fjallstrom Date: Fri, 17 Jul 2015 18:15:36 -0700 Subject: Power mods: Turning off VDD1 and VDD2, fixed timing issues with tps wake-up, other robustness fixes. Fixes from Sasha. Change-Id: I68cb2fb32a9749558a2eeecd916d64b2c2fbf096 --- arch/arm/boot/dts/omap3_h1.dts | 22 ++++++++++++++++------ drivers/mfd/tps65910.c | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/omap3_h1.dts b/arch/arm/boot/dts/omap3_h1.dts index af587d7f57f..a3e92d76f1f 100644 --- a/arch/arm/boot/dts/omap3_h1.dts +++ b/arch/arm/boot/dts/omap3_h1.dts @@ -100,7 +100,7 @@ /* listed below will be reported as the wakeup reason */ /* */ /* off IRQ handle */ - ti,pad_irq = <0x16e 90 1>, /* uart3 - serial rx */ + ti,pad_irq = <0x16e 90 0>, /* uart3 - serial rx */ <0x9f6 143 1>, /* mpu6515 irq pin - is this offset correct? */ <0x9f4 123 1>, /* BT host wake */ <0x1b0 23 1>; /* sys_nirq */ @@ -109,6 +109,7 @@ sound { compatible = "olio,omap-soc-omap3h1"; olio,mcbsp = <&mcbsp3>; + olio,mic_enable = <&gpio5 18 0>; }; }; @@ -131,7 +132,7 @@ sys_off_mode; auto_off; auto_retention; - offmodesetup_time = <3500>; + offmodesetup_time = <6000>; clksetup_time = <1000>; }; @@ -182,7 +183,7 @@ 0x0dc 0x004 /* CAM_HS, MODE4 | OUTPUT */ - /* USB */ + /* USB */ 0x172 0x100 /* HSUSB0_CLK, (OMAP_MUX_MODE0 | OMAP_PIN_INPUT) */ 0x174 0x000 /* HSUSB0_STP, (OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT) */ @@ -206,7 +207,7 @@ 0x0da 0x1604 /* DSS_DATA23, (IDIS | PI | M4 ) */ /* UART3 pins */ - 0x16e 0x4100 /* RX, input, off wake up */ + 0x16e 0x100 /* RX, input, off wake up */ 0x170 0x000 /* TX, output */ /* GPIO146, aka UART2TX, aka Microphone enable */ @@ -220,6 +221,14 @@ but this location makes it not function as an interrupt... ??? */ /* 0x9f6 0x4104 */ /* JTAG_EMU1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT | OMAP_PIN_OFF_WAKEUPENABLE */ + + /* UART 1 needs to be in safe mode for FCC tests */ + /* + 0x14c 0x007 + 0x14e 0x007 + 0x150 0x007 + 0x152 0x007 + */ >; }; @@ -306,6 +315,7 @@ regulators { vrtc_reg: regulator@0 { regulator-always-on; + ti,regulator-ext-sleep-control = <8>; }; /* DSS is on this one */ @@ -328,7 +338,7 @@ regulator-name = "vdd_mpu_iva"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <1350000>; - /* ti,regulator-ext-sleep-control = <8>; */ + ti,regulator-ext-sleep-control = <8>; }; vdd2_reg: regulator@3 { @@ -341,7 +351,7 @@ regulator-name = "vdd_core"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <1200000>; - /* ti,regulator-ext-sleep-control = <8>; */ + ti,regulator-ext-sleep-control = <8>; }; /* not used, I think */ diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 15f2c8dea2f..dbf85fc07d2 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -26,6 +26,7 @@ #include #include #include +#include static struct resource rtc_resources[] = { { @@ -225,6 +226,29 @@ static struct regmap_irq_chip tps65910_irq_chip = { .ack_base = TPS65910_INT_STS, }; +static int tps65910_irq; + +static int tps65910_irq_pm_notifier(struct notifier_block *notifier, + unsigned long pm_event, void *unused) +{ + switch (pm_event) { + case PM_SUSPEND_PREPARE: + disable_irq(tps65910_irq); + break; + case PM_POST_SUSPEND: + enable_irq(tps65910_irq); + break; + default: + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block tps65910_irq_pm_notifier_block = { + .notifier_call = tps65910_irq_pm_notifier, +}; + static int tps65910_irq_init(struct tps65910 *tps65910, int irq, struct tps65910_platform_data *pdata) { @@ -251,6 +275,8 @@ static int tps65910_irq_init(struct tps65910 *tps65910, int irq, } tps65910->chip_irq = irq; + tps65910_irq = irq; + register_pm_notifier(&tps65910_irq_pm_notifier_block); ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq, IRQF_ONESHOT, pdata->irq_base, tps6591x_irqs_chip, &tps65910->irq_data); -- cgit v1.2.3-70-g09d2 From 8db19ebb8e7405403b0dc670e76b84ff1b08d6b0 Mon Sep 17 00:00:00 2001 From: mattis fjallstrom Date: Fri, 17 Jul 2015 18:16:15 -0700 Subject: Updated ALS driver with the latest from Capella. Change-Id: I43b36fedc831aae7e2f77fc975dbf2feb9cd9b49 --- drivers/iio/light/cm3391.c | 277 ++++++++++++++++++++++++++------------------- 1 file changed, 162 insertions(+), 115 deletions(-) diff --git a/drivers/iio/light/cm3391.c b/drivers/iio/light/cm3391.c index ed2d84a61fe..abe8b8e7f5c 100644 --- a/drivers/iio/light/cm3391.c +++ b/drivers/iio/light/cm3391.c @@ -20,7 +20,6 @@ #include #include #include - #include #ifdef CONFIG_ACPI @@ -30,51 +29,60 @@ #define OLDAPI /* Registers Address */ -#define CM3391_REG_ADDR_CMD 0x00 -#define CM3391_REG_ADDR_TEST 0x01 -#define CM3391_REG_ADDR_WH 0x02 -#define CM3391_REG_ADDR_WL 0x03 -#define CM3391_REG_ADDR_RED 0x08 -#define CM3391_REG_ADDR_ALS 0x09 -#define CM3391_REG_ADDR_BLUE 0x0A -#define CM3391_REG_ADDR_CLEAR 0x0B -#define CM3391_REG_ADDR_ID 0x0C -#define CM3391_REG_ADDR_STATUS 0x0D +#define CM3391_REG_ADDR_CMD 0x00 +#define CM3391_REG_ADDR_TEST 0x01 +#define CM3391_REG_ADDR_WH 0x02 +#define CM3391_REG_ADDR_WL 0x03 +#define CM3391_REG_ADDR_RED 0x08 +#define CM3391_REG_ADDR_ALS 0x09 +#define CM3391_REG_ADDR_BLUE 0x0A +#define CM3391_REG_ADDR_CLEAR 0x0B +#define CM3391_REG_ADDR_ID 0x0C +#define CM3391_REG_ADDR_STATUS 0x0D /* Number of Configurable Registers */ -#define CM3391_CONF_REG_NUM 16 +#define CM3391_CONF_REG_NUM 16 /* CMD register */ -#define CM3391_CMD_CS_DISABLE BIT(0) -#define CM3391_CMD_CS_INT_EN BIT(8) - -#define CM3391_CMD_CS_PERS_SHIFT 10 -#define CM3391_CMD_CS_PERS_MASK (0x03 << CM3391_CMD_CS_PERS_SHIFT) -#define CM3391_CMD_CS_PERS_DEFAULT (0x01 << CM3391_CMD_CS_PERS_SHIFT) - -#define CM3391_CMD_CS_IT_SHIFT 4 -#define CM3391_CMD_CS_IT_MASK (0x07 << CM3391_CMD_CS_IT_SHIFT) -#define CM3391_CMD_CS_IT_DEFAULT (0x01 << CM3391_CMD_CS_IT_SHIFT) - -#define CM3391_CMD_CS_HS_SHIFT 3 -#define CM3391_CMD_CS_HS_MASK (0x01 << CM3391_CMD_CS_HS_SHIFT) -#define CM3391_CMD_CS_HS_DEFAULT (0x00 << CM3391_CMD_CS_HS_SHIFT) - -#define CM3391_CMD_DEFAULT (\ - CM3391_CMD_CS_PERS_DEFAULT |\ - CM3391_CMD_CS_IT_DEFAULT |\ - CM3391_CMD_CS_HS_DEFAULT) - -#define CM3391_WH_DEFAULT 0xFFFF -#define CM3391_WL_DEFAULT 0x0000 - -#define CM3391_CALIBSCALE_DEFAULT 100000 -#define CM3391_CALIBSCALE_RESOLUTION 100000 -#define CM3391_MLUX_PER_LUX 1000 -#define CM3391_THRESHOLD_PERCENT 10 /* 10 percent */ +#define CM3391_CMD_CS_DISABLE BIT(0) +#define CM3391_CMD_CS_INT_EN BIT(8) + +#define CM3391_CMD_CS_PERS_SHIFT 10 +#define CM3391_CMD_CS_PERS_MASK (BIT(10) | BIT(11)) +#define CM3391_CMD_CS_PERS_DEFAULT (0x01 << CM3391_CMD_CS_PERS_SHIFT) + +#define CM3391_CMD_CS_IT_SHIFT 4 +#define CM3391_CMD_CS_IT_MASK (BIT(4) | BIT(5) | BIT(6)) +#define CM3391_CMD_CS_IT_DEFAULT (0x01 << CM3391_CMD_CS_IT_SHIFT) + +#define CM3391_CMD_CS_HS_SHIFT BIT(3) + +#define CM3391_CMD_DEFAULT (CM3391_CMD_CS_PERS_DEFAULT |\ + CM3391_CMD_CS_IT_DEFAULT) + +#define CM3391_WH_DEFAULT 0xFFFF +#define CM3391_WL_DEFAULT 0x0000 + +#define CM3391_CALIBSCALE_DEFAULT 100000 +#define CM3391_CALIBSCALE_RESOLUTION 100000 +#define CM3391_MLUX_PER_LUX 1000 +#define CM3391_THRESHOLD_PERCENT 10 /* 10 percent */ + +#define CM3391_MLUX_PER_BIT_DEFAULT 550 +#define CM3391_MLUX_PER_BIT_BASE_IT 100000 + +static const struct { + int val; + int val2; + u8 it; +} cm3391_cs_it_scales[] = { + {0, 50000, 0}, /* 0.050000 */ + {0, 100000, 1}, /* 0.100000 */ + {0, 200000, 2}, /* 0.200000 */ + {0, 400000, 3}, /* 0.400000 */ + {0, 800000, 4}, /* 0.800000 */ +}; -#define CM3391_MLUX_PER_BIT_DEFAULT 550 -#define CM3391_MLUX_PER_BIT_BASE_IT 100000 static const int CM3391_cs_it_bits[] = { 0, 1, 2, 3, 4}; static const int CM3391_cs_it_values[] = { 50000, 100000, 200000, 400000, 800000}; @@ -111,7 +119,7 @@ struct cm3391_chip { static int cm3391_get_lux(struct cm3391_chip *chip); static int cm3391_threshold_update(struct cm3391_chip *chip, int percent); -static int cm3391_read_cs_it(struct cm3391_chip *chip, int *val2); +static int cm3391_read_cs_it(struct cm3391_chip *chip, int *val, int *val2); /** * cm3391_interrupt_config() - Enable/Disable CM3391 interrupt @@ -202,7 +210,7 @@ static int cm3391_acpi_get_cpm_info(struct i2c_client *client, char *obj_name, * cm3391_reg_init() - Initialize CM3391 registers * @chip: pointer of struct cm3391. * - * Initialize CM3391 color sensor register to default values. + * Initialize CM3391 color sensor registers to default values. * Return: 0 for success; otherwise for error code. */ @@ -217,7 +225,6 @@ static int cm3391_reg_init(struct cm3391_chip *chip) u64 cpm_elems[20]; #endif /* CONFIG_ACPI */ - /* Default device */ cs_info = chip->cs_info = &cm3391_cs_info_default; chip->conf_regs[CM3391_REG_ADDR_CMD] = CM3391_CMD_DEFAULT; @@ -237,14 +244,11 @@ static int cm3391_reg_init(struct cm3391_chip *chip) /* Identify device */ ret = i2c_smbus_read_word_data(client, CM3391_REG_ADDR_ID); if (ret < 0) - return ret; - + return ret; if ((ret & 0xFF) != 0x91) return -ENODEV; #ifdef CONFIG_ACPI -#error ACPI is enabled, strange! OLIO MFJ - if (ACPI_HANDLE(&client->dev)) { /* Load from ACPI */ cpm_elem_count = cm3391_acpi_get_cpm_info(client, "CPM0", @@ -281,34 +285,81 @@ static int cm3391_reg_init(struct cm3391_chip *chip) ret = i2c_smbus_write_word_data(client, i, chip->conf_regs[i]); if (ret < 0) - return ret; + return ret; } } return 0; } +void cm3391_autoit(struct cm3391_chip *chip, u16 als_raw) +{ + struct i2c_client *client = chip->client; + u16 cs_it, cmd; + int i; + int update; + s32 ret; + + cs_it = chip->conf_regs[CM3391_REG_ADDR_CMD]; + cs_it &= CM3391_CMD_CS_IT_MASK; + cs_it >>= CM3391_CMD_CS_IT_SHIFT; + for (i = 0; i < ARRAY_SIZE(cm3391_cs_it_scales); i++) + if (cs_it == cm3391_cs_it_scales[i].it) + break; + update = 0; + if (als_raw > 60000) { + if (i > 0) { + i--; + update = 1; + } + } + if (als_raw < 100) { + if (i < ARRAY_SIZE(cm3391_cs_it_scales) - 1) { + i++; + update = 1; + } + } + + if (update) { + cs_it = cm3391_cs_it_scales[i].it; + cs_it <<= CM3391_CMD_CS_IT_SHIFT; + + cmd = chip->conf_regs[CM3391_REG_ADDR_CMD]; + cmd &= ~CM3391_CMD_CS_IT_MASK; + cmd |= cs_it; + ret = i2c_smbus_write_word_data(client, + CM3391_REG_ADDR_CMD, cmd); + + if (ret < 0) + return; + + chip->conf_regs[CM3391_REG_ADDR_CMD] = cmd; + return; + } +} + /** - * cm3391_read_cs_it() - Get sensor integration time (ms) + * cm3391_read_cs_it() - Get sensor integration time * @chip: pointer of struct cm3391 - * @val2: pointer of int to load the cs_it value. + * #val: pointer of int to load the integration time(sec). + * @val2: pointer of int to load the integration time(microsecond). * - * Report the current integration time in milliseconds. + * Report the current integration time. * * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL. */ -static int cm3391_read_cs_it(struct cm3391_chip *chip, int *val2) +static int cm3391_read_cs_it(struct cm3391_chip *chip, int *val, int *val2) { - struct cm3391_cs_info *cs_info = chip->cs_info; u16 cs_it; int i; cs_it = chip->conf_regs[CM3391_REG_ADDR_CMD]; cs_it &= CM3391_CMD_CS_IT_MASK; cs_it >>= CM3391_CMD_CS_IT_SHIFT; - for (i = 0; i < cs_info->num_cs_it; i++) { - if (cs_it == cs_info->cs_it_bits[i]) { - *val2 = cs_info->cs_it_values[i]; + for (i = 0; i < ARRAY_SIZE(cm3391_cs_it_scales); i++) { + if (cs_it == cm3391_cs_it_scales[i].it) { + *val = cm3391_cs_it_scales[i].val; + *val2 = cm3391_cs_it_scales[i].val2; return IIO_VAL_INT_PLUS_MICRO; } } @@ -326,31 +377,33 @@ static int cm3391_read_cs_it(struct cm3391_chip *chip, int *val2) * * Return: i2c_smbus_write_word_data command return value. */ -static int cm3391_write_cs_it(struct cm3391_chip *chip, int val) +static int cm3391_write_cs_it(struct cm3391_chip *chip, int val, int val2) { struct i2c_client *client = chip->client; - struct cm3391_cs_info *cs_info = chip->cs_info; - u16 cs_it; - int ret, i; + u16 cs_it, cmd; + int i; + s32 ret; - for (i = 0; i < cs_info->num_cs_it; i++) - if (val <= cs_info->cs_it_values[i]) - break; - if (i >= cs_info->num_cs_it) - i = cs_info->num_cs_it - 1; + for (i = 0; i < ARRAY_SIZE(cm3391_cs_it_scales); i++) { + if (val == cm3391_cs_it_scales[i].val && + val2 == cm3391_cs_it_scales[i].val2) { - cs_it = cs_info->cs_it_bits[i]; - cs_it <<= CM3391_CMD_CS_IT_SHIFT; + cs_it = cm3391_cs_it_scales[i].it; + cs_it <<= CM3391_CMD_CS_IT_SHIFT; - mutex_lock(&chip->lock); - chip->conf_regs[CM3391_REG_ADDR_CMD] &= - ~CM3391_CMD_CS_IT_MASK; - chip->conf_regs[CM3391_REG_ADDR_CMD] |= - cs_it; - ret = i2c_smbus_write_word_data(client, CM3391_REG_ADDR_CMD, - chip->conf_regs[CM3391_REG_ADDR_CMD]); - mutex_unlock(&chip->lock); + cmd = chip->conf_regs[CM3391_REG_ADDR_CMD]; + cmd &= ~CM3391_CMD_CS_IT_MASK; + cmd |= cs_it; + ret = i2c_smbus_write_word_data(client, + CM3391_REG_ADDR_CMD, cmd); + if (ret < 0) + return ret; + + chip->conf_regs[CM3391_REG_ADDR_CMD] = cmd; + return 0; + } + } return ret; } #endif /* !OLDAPI */ @@ -369,34 +422,37 @@ static int cm3391_get_lux(struct cm3391_chip *chip) struct i2c_client *client = chip->client; struct cm3391_cs_info *cs_info = chip->cs_info; int ret; + int val, val2; int cs_it; - u64 tmp; + u64 lux; /* Calculate mlux per bit based on cs_it */ - ret = cm3391_read_cs_it(chip, &cs_it); + ret = cm3391_read_cs_it(chip, &val, &val2); if (ret < 0) return -EINVAL; - tmp = (__force u64)cs_info->mlux_per_bit; - tmp *= cs_info->mlux_per_bit_base_it; - tmp = div_u64(tmp, cs_it); + cs_it = val * 1000000 + val2; + lux = (__force u64)cs_info->mlux_per_bit; + lux *= cs_info->mlux_per_bit_base_it; + lux = div_u64(lux, cs_it); /* Get als_raw */ - if (!(chip->conf_regs[CM3391_REG_ADDR_CMD] & CM3391_CMD_CS_INT_EN)) - cs_info->als_raw = i2c_smbus_read_word_data( - client, - CM3391_REG_ADDR_ALS); - if (cs_info->als_raw < 0) - return cs_info->als_raw; + ret = i2c_smbus_read_word_data(client, CM3391_REG_ADDR_ALS); + if (ret < 0) { + dev_err(&client->dev, "Error reading reg_addr_als\n"); + return ret; + } + cs_info->als_raw = (u16)ret; + lux *= cs_info->als_raw; + lux *= cs_info->calibscale; + lux = div_u64(lux, CM3391_CALIBSCALE_RESOLUTION); + lux = div_u64(lux, CM3391_MLUX_PER_LUX); - tmp *= cs_info->als_raw; - tmp *= cs_info->calibscale; - tmp = div_u64(tmp, CM3391_CALIBSCALE_RESOLUTION); - tmp = div_u64(tmp, CM3391_MLUX_PER_LUX); + if (lux > 0xFFFF) + lux = 0xFFFF; - if (tmp > 0xFFFF) - tmp = 0xFFFF; + cm3391_autoit(chip, cs_info->als_raw); - return (int)tmp; + return (int)lux; } static int cm3391_read_raw(struct iio_dev *indio_dev, @@ -426,10 +482,9 @@ static int cm3391_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; #ifndef OLDAPI case IIO_CHAN_INFO_INT_TIME: - *val = 0; - ret = cm3391_read_cs_it(chip, val2); + ret = cm3391_read_cs_it(chip, val, val2); return ret; -#endif /* !OLDAPI */ +#endif /* OLDAPI */ } return -EINVAL; @@ -441,26 +496,22 @@ static int cm3391_write_raw(struct iio_dev *indio_dev, { struct cm3391_chip *chip = iio_priv(indio_dev); struct cm3391_cs_info *cs_info = chip->cs_info; -#ifndef OLDAPI - long ms; -#endif /* !OLDAPI */ switch (mask) { case IIO_CHAN_INFO_CALIBSCALE: cs_info->calibscale = val; - return val; + return 0; #ifndef OLDAPI case IIO_CHAN_INFO_INT_TIME: - ms = val * 1000000 + val2; - return cm3391_write_cs_it(chip, (int)ms); -#endif /* !OLDAPI */ + return cm3391_write_cs_it(chip, val, val2); +#endif /* OLDAPI */ } return -EINVAL; } /** - * cm3391_get_it_available() - Get available IT value + * cm3391_get_it_available() - Get available CS IT value * @dev: pointer of struct device. * @attr: pointer of struct device_attribute. * @buf: pointer of return string buffer. @@ -472,14 +523,12 @@ static int cm3391_write_raw(struct iio_dev *indio_dev, static ssize_t cm3391_get_it_available(struct device *dev, struct device_attribute *attr, char *buf) { - struct cm3391_chip *chip = iio_priv(dev_to_iio_dev(dev)); - struct cm3391_cs_info *cs_info = chip->cs_info; int i, len; - for (i = 0, len = 0; i < cs_info->num_cs_it; i++) + for (i = 0, len = 0; i < ARRAY_SIZE(cm3391_cs_it_scales); i++) len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ", - cs_info->cs_it_values[i]/1000000, - cs_info->cs_it_values[i]%1000000); + cm3391_cs_it_scales[i].val, + cm3391_cs_it_scales[i].val2); return len + scnprintf(buf + len, PAGE_SIZE - len, "\n"); } @@ -582,14 +631,13 @@ static const struct iio_chan_spec cm3391_channels[] = { .type = IIO_LIGHT, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | - BIT(IIO_CHAN_INFO_CALIBSCALE) + BIT(IIO_CHAN_INFO_CALIBSCALE), }, CM3391_COLOR_CHANNEL(RED, CM3391_REG_ADDR_RED), CM3391_COLOR_CHANNEL(GREEN, CM3391_REG_ADDR_ALS), CM3391_COLOR_CHANNEL(BLUE, CM3391_REG_ADDR_BLUE), CM3391_COLOR_CHANNEL(CLEAR, CM3391_REG_ADDR_CLEAR), }; - #else #define CM3391_COLOR_CHANNEL(_color, _addr) { \ .type = IIO_INTENSITY, \ @@ -613,7 +661,7 @@ static const struct iio_chan_spec cm3391_channels[] = { CM3391_COLOR_CHANNEL(BLUE, CM3391_REG_ADDR_BLUE), CM3391_COLOR_CHANNEL(CLEAR, CM3391_REG_ADDR_CLEAR), }; -#endif /* !OLDAPI */ +#endif /* OLDAPI */ static IIO_DEVICE_ATTR(in_illuminance_integration_time_available, S_IRUGO, cm3391_get_it_available, NULL, 0); @@ -644,7 +692,7 @@ static int cm3391_probe(struct i2c_client *client, #ifdef OLDAPI indio_dev = iio_device_alloc(sizeof(*chip)); if (!indio_dev) { - dev_err(&client->dev, "iio_device_alloc fails\n"); + dev_err(&client->dev, "iio_device_alloc failed\n"); return -ENOMEM; } #else @@ -723,7 +771,6 @@ error_free_irq: #endif /* OLDAPI */ error_disable_int: cm3391_interrupt_config(chip, 0); - return ret; } -- cgit v1.2.3-70-g09d2 From 3413080107b5540bb7d1838cb1ced950e96a867e Mon Sep 17 00:00:00 2001 From: mattis fjallstrom Date: Fri, 17 Jul 2015 18:40:17 -0700 Subject: Refactor fixes for tps65910, fixes from Sasha Change-Id: I8aee8f4304aa1ef8e9607f4674487d8e32ff5eaa --- arch/arm/boot/dts/omap3_h1.dts | 3 +++ drivers/mfd/tps65910.c | 34 +++++++++++++++++++--------------- include/linux/mfd/tps65910.h | 3 ++- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/arch/arm/boot/dts/omap3_h1.dts b/arch/arm/boot/dts/omap3_h1.dts index a3e92d76f1f..5673768878d 100644 --- a/arch/arm/boot/dts/omap3_h1.dts +++ b/arch/arm/boot/dts/omap3_h1.dts @@ -300,6 +300,9 @@ interrupt-controller; ti,en-ck32k-xtal; + ti,en-dev-slp; + ti,sleepsig-pol; + ti,clkout32k-keepon; /* set SR_CTL_I2C_SEL - access to smartreflex registers by control i2c */ ti,system-power-controller; diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index dbf85fc07d2..1e7ef2a2e35 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -363,7 +363,13 @@ static int tps65910_sleepinit(struct tps65910 *tps65910, dev = tps65910->dev; - /* set polarity of SLLEEPSIG requst ot enter OFF mode */ + if (!pmic_pdata->en_dev_slp) + return 0; + + /* + * set polarity of SLLEEPSIG requst to enter OFF mode + * before enabling sleep + */ ret = tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL2, DEVCTRL2_SLEEPSIG_POL_MASK); if (ret < 0) { @@ -379,18 +385,7 @@ static int tps65910_sleepinit(struct tps65910 *tps65910, goto err_sleep_init; } - ret = tps65910_reg_set_bits(tps65910, TPS65910_SLEEP_KEEP_RES_ON, - SLEEP_KEEP_RES_ON_CLKOUT32K_KEEPON_MASK); - if (ret < 0) { - dev_err(dev, "set sleep_keep_res_on failed: %d\n", ret); - goto err_sleep_init; - } - - /* Return if there is no sleep keepon data. */ - if (!pmic_pdata->slp_keepon) - return 0; - - if (pmic_pdata->slp_keepon->therm_keepon) { + if (pmic_pdata->slp_keepon.therm_keepon) { ret = tps65910_reg_set_bits(tps65910, TPS65910_SLEEP_KEEP_RES_ON, SLEEP_KEEP_RES_ON_THERM_KEEPON_MASK); @@ -400,7 +395,7 @@ static int tps65910_sleepinit(struct tps65910 *tps65910, } } - if (pmic_pdata->slp_keepon->clkout32k_keepon) { + if (pmic_pdata->slp_keepon.clkout32k_keepon) { ret = tps65910_reg_set_bits(tps65910, TPS65910_SLEEP_KEEP_RES_ON, SLEEP_KEEP_RES_ON_CLKOUT32K_KEEPON_MASK); @@ -410,7 +405,7 @@ static int tps65910_sleepinit(struct tps65910 *tps65910, } } - if (pmic_pdata->slp_keepon->i2chs_keepon) { + if (pmic_pdata->slp_keepon.i2chs_keepon) { ret = tps65910_reg_set_bits(tps65910, TPS65910_SLEEP_KEEP_RES_ON, SLEEP_KEEP_RES_ON_I2CHS_KEEPON_MASK); @@ -477,6 +472,15 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, prop = of_property_read_bool(np, "ti,en-ck32k-xtal"); board_info->en_ck32k_xtal = prop; + prop = of_property_read_bool(np, "ti,en-dev-slp"); + board_info->en_dev_slp = prop; + + prop = of_property_read_bool(np, "ti,sleepsig-pol"); + board_info->sleepsig_pol = prop; + + prop = of_property_read_bool(np, "ti,clkout32k-keepon"); + board_info->slp_keepon.clkout32k_keepon = prop; + board_info->irq = client->irq; board_info->irq_base = -1; board_info->pm_off = of_property_read_bool(np, diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index 20e433e551e..7f0ec4340a3 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -878,8 +878,9 @@ struct tps65910_board { int vmbch2_threshold; bool en_ck32k_xtal; bool en_dev_slp; + bool sleepsig_pol; bool pm_off; - struct tps65910_sleep_keepon_data *slp_keepon; + struct tps65910_sleep_keepon_data slp_keepon; bool en_gpio_sleep[TPS6591X_MAX_NUM_GPIO]; unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS]; struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS]; -- cgit v1.2.3-70-g09d2