Beispiel #1
0
int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
					u32 usage_id,
					struct hid_sensor_common *st)
{

	struct hid_sensor_hub_attribute_info timestamp;
	s32 value;
	int ret;

	hid_sensor_get_reporting_interval(hsdev, usage_id, st);

	sensor_hub_input_get_attribute_info(hsdev,
					HID_FEATURE_REPORT, usage_id,
					HID_USAGE_SENSOR_PROP_REPORT_STATE,
					&st->report_state);

	sensor_hub_input_get_attribute_info(hsdev,
					HID_FEATURE_REPORT, usage_id,
					HID_USAGE_SENSOR_PROY_POWER_STATE,
					&st->power_state);

	sensor_hub_input_get_attribute_info(hsdev,
			HID_FEATURE_REPORT, usage_id,
			HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS,
			 &st->sensitivity);

	st->raw_hystersis = -1;

	sensor_hub_input_get_attribute_info(hsdev,
					    HID_INPUT_REPORT, usage_id,
					    HID_USAGE_SENSOR_TIME_TIMESTAMP,
					    &timestamp);
	if (timestamp.index >= 0 && timestamp.report_id) {
		int val0, val1;

		hid_sensor_format_scale(HID_USAGE_SENSOR_TIME_TIMESTAMP,
					&timestamp, &val0, &val1);
		st->timestamp_ns_scale = val0;
	} else
		st->timestamp_ns_scale = 1000000000;

	hid_sensor_get_report_latency_info(hsdev, usage_id, st);

	hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x %x:%x\n",
		st->poll.index, st->poll.report_id,
		st->report_state.index, st->report_state.report_id,
		st->power_state.index, st->power_state.report_id,
		st->sensitivity.index, st->sensitivity.report_id,
		timestamp.index, timestamp.report_id);

	ret = sensor_hub_get_feature(hsdev,
				st->power_state.report_id,
				st->power_state.index, sizeof(value), &value);
	if (ret < 0)
		return ret;
	if (value < 0)
		return -EINVAL;

	return 0;
}
Beispiel #2
0
int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st,
					int val1, int val2)
{
	s32 value;
	int ret;

	if (val1 < 0 || val2 < 0)
		return -EINVAL;

	value = convert_to_vtf_format(st->sensitivity.size,
				st->sensitivity.unit_expo,
				val1, val2);
	ret = sensor_hub_set_feature(st->hsdev, st->sensitivity.report_id,
				     st->sensitivity.index, sizeof(value),
				     &value);
	if (ret < 0 || value < 0)
		return -EINVAL;

	ret = sensor_hub_get_feature(st->hsdev,
				     st->sensitivity.report_id,
				     st->sensitivity.index, sizeof(value),
				     &value);
	if (ret < 0 || value < 0)
		return -EINVAL;

	st->raw_hystersis = value;

	return 0;
}
Beispiel #3
0
int hid_sensor_read_samp_freq_value(struct hid_sensor_common *st,
				int *val1, int *val2)
{
	s32 value;
	int ret;

	ret = sensor_hub_get_feature(st->hsdev,
				     st->poll.report_id,
				     st->poll.index, sizeof(value), &value);
	if (ret < 0 || value < 0) {
		*val1 = *val2 = 0;
		return -EINVAL;
	} else {
		if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND)
			simple_div(1000, value, val1, val2);
		else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND)
			simple_div(1, value, val1, val2);
		else {
			*val1 = *val2 = 0;
			return -EINVAL;
		}
	}

	return IIO_VAL_INT_PLUS_MICRO;
}
Beispiel #4
0
int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st,
				int val1, int val2)
{
	s32 value;
	int ret;

	if (val1 < 0 || val2 < 0)
		return -EINVAL;

	value = val1 * pow_10(6) + val2;
	if (value) {
		if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND)
			value = pow_10(9)/value;
		else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND)
			value = pow_10(6)/value;
		else
			value = 0;
	}
	ret = sensor_hub_set_feature(st->hsdev, st->poll.report_id,
				     st->poll.index, sizeof(value), &value);
	if (ret < 0 || value < 0)
		return -EINVAL;

	ret = sensor_hub_get_feature(st->hsdev,
				     st->poll.report_id,
				     st->poll.index, sizeof(value), &value);
	if (ret < 0 || value < 0)
		return -EINVAL;

	st->poll_interval = value;

	return 0;
}
Beispiel #5
0
static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
{
	int state_val;
	int report_val;
	s32 poll_value = 0;

	if (state) {
		if (sensor_hub_device_open(st->hsdev))
			return -EIO;

		atomic_inc(&st->data_ready);

		state_val = hid_sensor_get_usage_index(st->hsdev,
			st->power_state.report_id,
			st->power_state.index,
			HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM);
		report_val = hid_sensor_get_usage_index(st->hsdev,
			st->report_state.report_id,
			st->report_state.index,
			HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM);

		poll_value = hid_sensor_read_poll_value(st);
	} else {
		if (!atomic_dec_and_test(&st->data_ready))
			return 0;
		sensor_hub_device_close(st->hsdev);
		state_val = hid_sensor_get_usage_index(st->hsdev,
			st->power_state.report_id,
			st->power_state.index,
			HID_USAGE_SENSOR_PROP_POWER_STATE_D4_POWER_OFF_ENUM);
		report_val = hid_sensor_get_usage_index(st->hsdev,
			st->report_state.report_id,
			st->report_state.index,
			HID_USAGE_SENSOR_PROP_REPORTING_STATE_NO_EVENTS_ENUM);
	}

	if (state_val >= 0) {
		state_val += st->power_state.logical_minimum;
		sensor_hub_set_feature(st->hsdev, st->power_state.report_id,
					st->power_state.index,
					(s32)state_val);
	}

	if (report_val >= 0) {
		report_val += st->report_state.logical_minimum;
		sensor_hub_set_feature(st->hsdev, st->report_state.report_id,
					st->report_state.index,
					(s32)report_val);
	}

	sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
					st->power_state.index,
					&state_val);
	if (state && poll_value)
		msleep_interruptible(poll_value * 2);

	return 0;
}
Beispiel #6
0
int hid_sensor_get_report_latency(struct hid_sensor_common *st)
{
	int ret;
	int value;

	ret = sensor_hub_get_feature(st->hsdev, st->report_latency.report_id,
				     st->report_latency.index, sizeof(value),
				     &value);
	if (ret < 0)
		return ret;

	return value;
}
static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
						bool state)
{
	struct hid_sensor_common *st = iio_trigger_get_drvdata(trig);
	s32 power_state_val;
	s32 report_state_val;

	st->data_ready = state;
	if (state) {
		power_state_val = hid_sensor_get_usage_index(st->hsdev,
			st->power_state.report_id,
			st->power_state.index,
			HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM);
		report_state_val = hid_sensor_get_usage_index(st->hsdev,
			st->report_state.report_id,
			st->report_state.index,
			HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM);
	} else {
		power_state_val = hid_sensor_get_usage_index(st->hsdev,
			st->power_state.report_id,
			st->power_state.index,
			HID_USAGE_SENSOR_PROP_POWER_STATE_D1_LOW_POWER_ENUM);
		report_state_val = hid_sensor_get_usage_index(st->hsdev,
			st->report_state.report_id,
			st->report_state.index,
			HID_USAGE_SENSOR_PROP_REPORTING_STATE_NO_EVENTS_ENUM);
	}
	power_state_val += st->power_state.logical_minimum;
	report_state_val += st->report_state.logical_minimum;
	if (power_state_val >= 0)
		sensor_hub_set_feature(st->hsdev, st->power_state.report_id,
						st->power_state.index,
						power_state_val);
	if (report_state_val >= 0)
		sensor_hub_set_feature(st->hsdev, st->report_state.report_id,
						st->report_state.index,
						report_state_val);

	/* Some hubs require this read as a 'sync' point. */
	sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
					st->power_state.index,
					&power_state_val);

	sensor_hub_set_feature(st->hsdev, st->conn_type.report_id,
					st->conn_type.index,
					hid_sensor_conn_type);

	return 0;
}
Beispiel #8
0
s32 hid_sensor_read_poll_value(struct hid_sensor_common *st)
{
	s32 value = 0;
	int ret;

	ret = sensor_hub_get_feature(st->hsdev,
				     st->poll.report_id,
				     st->poll.index, sizeof(value), &value);

	if (ret < 0 || value < 0) {
		return -EINVAL;
	} else {
		if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND)
			value = value * 1000;
	}

	return value;
}
int hid_sensor_read_raw_hyst_value(struct hid_sensor_iio_common *st,
				int *val1, int *val2)
{
	s32 value;
	int ret;

	ret = sensor_hub_get_feature(st->hsdev,
		st->sensitivity.report_id,
		st->sensitivity.index, &value);
	if (ret < 0 || value < 0) {
		*val1 = *val2 = 0;
		return -EINVAL;
	} else {
		convert_from_vtf_format(value, st->sensitivity.size,
					st->sensitivity.unit_expo,
					val1, val2);
	}

	return IIO_VAL_INT_PLUS_MICRO;
}
int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st,
				int val1, int val2)
{
	s32 value;
	int ret;
	s32 current_value = 0;

	if (val1 < 0 || val2 < 0)
		return -EINVAL;

	value = val1 * pow_10(6) + val2;
	if (value) {
		if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND)
			value = pow_10(9)/value;
		else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND)
			value = pow_10(6)/value;
		else
			value = 0;
	}
	ret = sensor_hub_set_feature(st->hsdev,
		st->poll.report_id,
		st->poll.index, value);
	if (ret < 0 || value < 0)
		return -EINVAL;
	ret = sensor_hub_get_feature(st->hsdev,
		st->poll.report_id,
		st->poll.index, &current_value);
	if (ret < 0) {
		printk(KERN_ERR "sensor_hub_get_feature failed\n");
		return ret;
	}
	if (current_value != value) {
		printk(KERN_ERR "sensor_hub_set_feature_failed\n");
		return -EINVAL;
	}
	return 0;
}