for (i = 0; i < sensorhub->sensor_num; i++) {
sensorhub->params->cmd = MOTIONSENSE_CMD_INFO;
sensorhub->params->info.sensor_num = i;
retries = CROS_EC_CMD_INFO_RETRIES; do {
ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); if (ret == -EBUSY) { /* The EC is still busy initializing sensors. */
usleep_range(5000, 6000);
retries--;
}
} while (ret == -EBUSY && retries);
if (ret < 0) {
dev_err(dev, "no info for EC sensor %d : %d/%d\n",
i, ret, msg->result); continue;
} if (retries < CROS_EC_CMD_INFO_RETRIES) {
dev_warn(dev, "%d retries needed to bring up sensor %d\n",
CROS_EC_CMD_INFO_RETRIES - retries, i);
}
switch (sensorhub->resp->info.type) { case MOTIONSENSE_TYPE_ACCEL:
name = "cros-ec-accel"; break; case MOTIONSENSE_TYPE_BARO:
name = "cros-ec-baro"; break; case MOTIONSENSE_TYPE_GYRO:
name = "cros-ec-gyro"; break; case MOTIONSENSE_TYPE_MAG:
name = "cros-ec-mag"; break; case MOTIONSENSE_TYPE_PROX:
name = "cros-ec-prox"; break; case MOTIONSENSE_TYPE_LIGHT:
name = "cros-ec-light"; break; case MOTIONSENSE_TYPE_ACTIVITY:
name = "cros-ec-activity"; break; default:
dev_warn(dev, "unknown type %d\n",
sensorhub->resp->info.type); continue;
}
ret = cros_ec_sensorhub_allocate_sensor(dev, name, i); if (ret) return ret;
sensor_type[sensorhub->resp->info.type]++;
}
if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2)
ec->has_kb_wake_angle = true;
if (cros_ec_check_features(ec,
EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS)) {
ret = cros_ec_sensorhub_allocate_sensor(dev, "cros-ec-lid-angle",
0); if (ret) return ret;
}
/* Check whether this EC is a sensor hub. */ if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) {
sensor_num = cros_ec_get_sensor_count(ec); if (sensor_num < 0) {
dev_err(dev, "Unable to retrieve sensor information (err:%d)\n",
sensor_num); return sensor_num;
} if (sensor_num == 0) {
dev_err(dev, "Zero sensors reported.\n"); return -EINVAL;
}
data->sensor_num = sensor_num;
/* * Prepare the ring handler before enumering the * sensors.
*/ if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
ret = cros_ec_sensorhub_ring_allocate(data); if (ret) return ret;
}
/* Enumerate the sensors.*/
ret = cros_ec_sensorhub_register(dev, data); if (ret) return ret;
/* * When the EC does not have a FIFO, the sensors will query * their data themselves via sysfs or a software trigger.
*/ if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
ret = cros_ec_sensorhub_ring_add(data); if (ret) return ret; /* * The msg and its data is not under the control of the * ring handler.
*/ return devm_add_action_or_reset(dev,
cros_ec_sensorhub_ring_remove,
data);
}
} else { /* * If the device has sensors but does not claim to * be a sensor hub, we are in legacy mode.
*/
data->sensor_num = 2; for (i = 0; i < data->sensor_num; i++) {
ret = cros_ec_sensorhub_allocate_sensor(dev, "cros-ec-accel-legacy", i); if (ret) return ret;
}
}
return 0;
}
#ifdef CONFIG_PM_SLEEP /* * When the EC is suspending, we must stop sending interrupt, * we may use the same interrupt line for waking up the device. * Tell the EC to stop sending non-interrupt event on the iio ring.
*/ staticint cros_ec_sensorhub_suspend(struct device *dev)
{ struct cros_ec_sensorhub *sensorhub = dev_get_drvdata(dev); struct cros_ec_dev *ec = sensorhub->ec;
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) return cros_ec_sensorhub_ring_fifo_enable(sensorhub, false); return 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.