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; }
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; }