drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c

Source file repositories/reference/linux-study-clean/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
Extension
.c
Size
24944 bytes
Lines
887
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret) {
			dev_warn(dev, "Can not access sensor info\n");
			return ret;
		}
		state->type = state->resp->info.type;
		loc = state->resp->info.location;
		if (loc == MOTIONSENSE_LOC_BASE)
			indio_dev->label = "accel-base";
		else if (loc == MOTIONSENSE_LOC_LID)
			indio_dev->label = "accel-display";
		else if (loc == MOTIONSENSE_LOC_CAMERA)
			indio_dev->label = "accel-camera";

		/* Set sign vector, only used for backward compatibility. */
		memset(state->sign, 1, CROS_EC_SENSOR_MAX_AXIS);

		for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++)
			state->calib[i].scale = MOTION_SENSE_DEFAULT_SCALE;

		/* 0 is a correct value used to stop the device */
		if (state->msg->version < 3) {
			get_default_min_max_freq(state->resp->info.type,
						 &frequencies[1],
						 &frequencies[2],
						 &state->fifo_max_event_count);
		} else {
			if (state->resp->info_3.max_frequency == 0) {
				get_default_min_max_freq(state->resp->info.type,
							 &frequencies[1],
							 &frequencies[2],
							 &temp);
			} else {
				frequencies[1] = state->resp->info_3.min_frequency;
				frequencies[2] = state->resp->info_3.max_frequency;
			}
			state->fifo_max_event_count = state->resp->info_3.fifo_max_event_count;
		}
		for (i = 0; i < ARRAY_SIZE(frequencies); i++) {
			state->frequencies[2 * i] = frequencies[i] / 1000;
			state->frequencies[2 * i + 1] =
				(frequencies[i] % 1000) * 1000;
		}

		if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
			/*
			 * Create a software buffer, feed by the EC FIFO.
			 * We can not use trigger here, as events are generated
			 * as soon as sample_frequency is set.
			 */
			ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev, NULL,
							      cros_ec_sensor_fifo_attributes);
			if (ret)
				return ret;

			/* Timestamp coming from FIFO are in ns since boot. */
			ret = iio_device_set_clock(indio_dev, CLOCK_BOOTTIME);
			if (ret)
				return ret;

		} else {
			/*
			 * The only way to get samples in buffer is to set a
			 * software trigger (systrig, hrtimer).
			 */
			ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
					NULL, trigger_capture, NULL);
			if (ret)
				return ret;
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(cros_ec_sensors_core_init);

/**
 * cros_ec_sensors_core_register() - Register callback to FIFO and IIO when
 * sensor is ready.
 * It must be called at the end of the sensor probe routine.
 * @dev:		device created for the sensor
 * @indio_dev:		iio device structure of the device
 * @push_data:          function to call when cros_ec_sensorhub receives
 *    a sample for that sensor.
 *
 * Return: 0 on success, -errno on failure.
 */
int cros_ec_sensors_core_register(struct device *dev,
				  struct iio_dev *indio_dev,
				  cros_ec_sensorhub_push_data_cb_t push_data)
{

Annotation

Implementation Notes