diff options
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h | 3 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c | 13 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c | 56 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c | 43 | ||||
| -rw-r--r-- | drivers/rtc/rtc-tps65910.c | 31 | 
5 files changed, 67 insertions, 79 deletions
| diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h index ba971628496..edc5de95b1d 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h @@ -139,7 +139,7 @@ struct lsm6ds3_data {  	struct wake_lock tap_wlock;  	u8 first_irq_from_resume;  	u8 reg_read; -#define SIXD_MASK_VALID_BITS (0x3f) +#define SIXD_MASK_VALID_BITS (0x21)  	u8 sixd_mask;  	u8 int1_save; @@ -236,6 +236,7 @@ int st_lsm6ds3_allocate_rings(struct lsm6ds3_data *cdata);  void st_lsm6ds3_deallocate_rings(struct lsm6ds3_data *cdata);  int st_lsm6ds3_trig_set_state(struct iio_trigger *trig, bool state);  void st_lsm6ds3_read_fifo(struct lsm6ds3_data *cdata, bool check_fifo_len, bool update_discard); +void st_lsm6ds3_push_tap_to_fifo(struct lsm6ds3_data *cdata);  int st_lsm6ds3_set_fifo_decimators_and_threshold(struct lsm6ds3_data *cdata);  #define ST_LSM6DS3_TRIGGER_SET_STATE (&st_lsm6ds3_trig_set_state)  #else /* CONFIG_IIO_BUFFER */ diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c index 87cea6f349a..2789d0dbd67 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c @@ -146,6 +146,17 @@ static void st_lsm6ds3_parse_fifo_data(struct lsm6ds3_data *cdata, u16 read_len)  	return;  } +void st_lsm6ds3_push_tap_to_fifo(struct lsm6ds3_data *cdata) +{ +	int i; +	u8 fake_tap[6] = {0};  +	dev_info(cdata->dev, "Sending Fake tap through accel data @:%llu", cdata->accel_timestamp-1); +	st_lsm6ds3_push_data_with_timestamp( +		cdata, ST_INDIO_DEV_ACCEL, +		fake_tap, +		cdata->accel_timestamp -1); +} +  void st_lsm6ds3_read_fifo(struct lsm6ds3_data *cdata, bool check_fifo_len, bool update_discard)  {  	int err; @@ -194,7 +205,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_info(cdata->dev, "first accel timestamp:%lld last:%lld ", cdata->accel_timestamp, cdata->timestamp); +				dev_dbg(cdata->dev, "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 499fda71e59..b0df8009aa8 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c @@ -918,20 +918,6 @@ int st_lsm6ds3_set_drdy_irq(struct lsm6ds3_sensor_data *sdata, bool state)  		}  		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; @@ -1116,37 +1102,19 @@ static int st_lsm6ds3_enable_sensors(struct lsm6ds3_sensor_data *sdata)  			return err;  		sdata->c_odr = st_lsm6ds3_odr_table.odr_avl[i].hz; - -		break; +		//enable tap and  +		//passthrough since we always want 6d and tap enabled; +		  	case ST_INDIO_DEV_SIGN_MOTION: +  		err = st_lsm6ds3_write_data_with_mask(sdata->cdata, -					ST_LSM6DS3_SIGN_MOTION_EN_ADDR, -					ST_LSM6DS3_SIGN_MOTION_EN_MASK, -					ST_LSM6DS3_EN_BIT, true); +						ST_LSM6DS3_MD1_ADDR, ST_LSM6DS3_6D_MD1_INT_MASK, ST_LSM6DS3_EN_BIT, true); +		if (err < 0) +			return err; +		err = st_lsm6ds3_write_data_with_mask(sdata->cdata, +						ST_LSM6DS3_MD1_ADDR, ST_LSM6DS3_SINGTAP_MD1_INT_MASK, ST_LSM6DS3_EN_BIT, 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:  		err = st_lsm6ds3_write_data_with_mask(sdata->cdata, @@ -1568,7 +1536,7 @@ 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 -	regval = 0x50;//tap threshold +	regval = 0x28;//tap threshold  	err = sdata->cdata->tf->write(sdata->cdata,  					ST_LSM6DS3_TAP_THS_6D_ADDR,  					1, ®val, false); @@ -1935,7 +1903,7 @@ static ssize_t st_lsm6ds3_sysfs_sixd_wake_mask_set(struct device *dev,  	uint32_t maskval;  	ret = sscanf(buf, "%i", &maskval);  	dev_info(sdata->cdata->dev, "read: 0x%x ", maskval); -	if(ret != 1 || maskval ){ +	if(ret != 1 || (maskval > SIXD_MASK_VALID_BITS)){  		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"); @@ -2319,7 +2287,7 @@ int st_lsm6ds3_common_suspend(struct lsm6ds3_data *cdata)  		if ((i == ST_INDIO_DEV_SIGN_MOTION) || (i == ST_INDIO_DEV_TILT))  			continue;  		if(i == ST_INDIO_DEV_ACCEL){ -			//stop the fifo +			//stop the fifo irq  			err = st_lsm6ds3_set_drdy_irq(sdata, false);  			cdata->int1_save = 1;  			continue; //do not disable  diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c index 1805e8f8fb5..905ad01a9bd 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c @@ -71,6 +71,8 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)  	u8 d6d_event = 0;  	u8 tap_event = 0;  	int wake_irq; +	int ignore_event = 0; +  	cdata = container_of((struct work_struct *)data_work, @@ -78,9 +80,7 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)  	wake_irq = last_wakeup_reason_test(cdata->irq); -//	if(!wake_lock_active(&cdata->wlock)) -//		wake_lock(&cdata->wlock); -	 mutex_lock(&cdata->fifo_lock);  +	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); @@ -90,12 +90,13 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)  	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"); +		dev_info(cdata->dev, "D6D IRQ val:0x%x mask:0x%x",  SIXD_MASK_VALID_BITS & d6d_src_reg, cdata->sixd_mask);  		if(cdata->sixd_mask & d6d_src_reg){  			d6d_event = 1;  			cdata->last_wakeup_source |= LSM6DS3_WAKEUP_6D;  		}  		else{ +			ignore_event = 1;  			dev_info(cdata->dev, "ignoring 6d interrupt, wrong axis. mask: 0x%x", cdata->sixd_mask);  		}  @@ -113,28 +114,23 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)  	}  	if(cdata->first_irq_from_resume && wake_irq){  		dev_info(cdata->dev, "First IRQ from a RESUME"); -		if(!d6d_event && !tap_event){ +		if(!d6d_event && !tap_event && !ignore_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(cdata->first_irq_from_resume){ -			st_lsm6ds3_read_fifo(cdata, true, true); -		} -		else{ -			st_lsm6ds3_read_fifo(cdata, true, false); -		} +	if(!ignore_event && (tap_event || d6d_event) && cdata->first_irq_from_resume){ +		dev_info(cdata->dev, "Setting wake lock"); +		wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(1500));  	}  //significant motion event processing -	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)); +	if(tap_event){ +		dev_info(cdata->dev, "Sending sig mot event(tap); ready:%i",cdata->sign_motion_event_ready); +		st_lsm6ds3_push_tap_to_fifo(cdata);  		iio_push_event(cdata->indio_dev[  			ST_INDIO_DEV_SIGN_MOTION],  			IIO_UNMOD_EVENT_CODE(IIO_SIGN_MOTION, @@ -144,6 +140,10 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)  			cdata->sign_motion_event_ready = false;  	} +	if (src_fifo & ST_LSM6DS3_FIFO_DATA_AVL) { +			st_lsm6ds3_read_fifo(cdata, true, true); +	} +  	if (src_value & ST_LSM6DS3_SRC_STEP_DETECTOR_DATA_AVL) {  		iio_push_event(cdata->indio_dev[ST_INDIO_DEV_STEP_DETECTOR],  				IIO_UNMOD_EVENT_CODE(IIO_STEP_DETECTOR, @@ -174,14 +174,13 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)  				cdata->timestamp);  	} -	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; +	if(cdata->first_irq_from_resume){ +		cdata->first_irq_from_resume = 0; +		st_lsm6ds3_reconfigure_fifo(cdata, false); +	} +	enable_irq(cdata->irq);  	return;  } diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c index cdbf1a2b251..2e4894b4732 100644 --- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c @@ -238,17 +238,20 @@ static int tps65910_rtc_probe(struct platform_device *pdev)  	tps_rtc = devm_kzalloc(&pdev->dev, sizeof(struct tps65910_rtc),  			GFP_KERNEL); -	if (!tps_rtc) -		return -ENOMEM; + +    if (!tps_rtc) { +        ret = -ENOMEM; +        goto fail_end; +    }  	/* Clear pending interrupts */  	ret = regmap_read(tps65910->regmap, TPS65910_RTC_STATUS, &rtc_reg);  	if (ret < 0) -		return ret; +      goto fail_end;  	ret = regmap_write(tps65910->regmap, TPS65910_RTC_STATUS, rtc_reg);  	if (ret < 0) -		return ret; +        goto fail_end;  	dev_dbg(&pdev->dev, "Enabling rtc-tps65910.\n"); @@ -256,18 +259,19 @@ static int tps65910_rtc_probe(struct platform_device *pdev)  	ret = regmap_update_bits(tps65910->regmap, TPS65910_DEVCTRL,  		DEVCTRL_RTC_PWDN_MASK, 0 << DEVCTRL_RTC_PWDN_SHIFT);  	if (ret < 0) -		return ret; +        goto fail_end;  	rtc_reg = TPS65910_RTC_CTRL_STOP_RTC;  	ret = regmap_write(tps65910->regmap, TPS65910_RTC_CTRL, rtc_reg);  	if (ret < 0) -		return ret; +        goto fail_end;  	irq  = platform_get_irq(pdev, 0);  	if (irq <= 0) {  		dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n", -			irq); -		return -ENXIO; +                 irq); +        ret = -ENXIO; +        goto fail_end;  	}  	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, @@ -275,23 +279,28 @@ static int tps65910_rtc_probe(struct platform_device *pdev)  		dev_name(&pdev->dev), &pdev->dev);  	if (ret < 0) {  		dev_err(&pdev->dev, "IRQ is not free.\n"); -		return ret; +        goto fail_end;  	}  	tps_rtc->irq = irq; -	device_set_wakeup_capable(&pdev->dev, 1); + +    device_init_wakeup(&pdev->dev, 1);  	tps_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,  		&tps65910_rtc_ops, THIS_MODULE);  	if (IS_ERR(tps_rtc->rtc)) {  		ret = PTR_ERR(tps_rtc->rtc);  		dev_err(&pdev->dev, "RTC device register: err %d\n", ret); -		return ret; +        goto fail_end;  	}  	platform_set_drvdata(pdev, tps_rtc); +  	wake_lock_init(&rtc_wake_lock, WAKE_LOCK_SUSPEND, "rtc_wake_lock");  	return 0; + +fail_end: +    return ret;  }  /* |