drivers/iio/light/cros_ec_light_prox.c

Source file repositories/reference/linux-study-clean/drivers/iio/light/cros_ec_light_prox.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/light/cros_ec_light_prox.c
Extension
.c
Size
7060 bytes
Lines
268
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: implementation source
Status
source 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

struct cros_ec_light_prox_state {
	/* Shared by all sensors */
	struct cros_ec_sensors_core_state core;

	struct iio_chan_spec channels[CROS_EC_LIGHT_PROX_MAX_CHANNELS];
};

static int cros_ec_light_prox_read(struct iio_dev *indio_dev,
				   struct iio_chan_spec const *chan,
				   int *val, int *val2, long mask)
{
	struct cros_ec_light_prox_state *st = iio_priv(indio_dev);
	u16 data = 0;
	s64 val64;
	int ret;
	int idx = chan->scan_index;

	mutex_lock(&st->core.cmd_lock);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (chan->type == IIO_PROXIMITY) {
			ret = cros_ec_sensors_read_cmd(indio_dev, 1 << idx,
						     (s16 *)&data);
			if (ret)
				break;
			*val = data;
			ret = IIO_VAL_INT;
		} else {
			ret = -EINVAL;
		}
		break;
	case IIO_CHAN_INFO_PROCESSED:
		if (chan->type == IIO_LIGHT) {
			ret = cros_ec_sensors_read_cmd(indio_dev, 1 << idx,
						     (s16 *)&data);
			if (ret)
				break;
			/*
			 * The data coming from the light sensor is
			 * pre-processed and represents the ambient light
			 * illuminance reading expressed in lux.
			 */
			*val = data;
			ret = IIO_VAL_INT;
		} else {
			ret = -EINVAL;
		}
		break;
	case IIO_CHAN_INFO_CALIBBIAS:
		st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_OFFSET;
		st->core.param.sensor_offset.flags = 0;

		ret = cros_ec_motion_send_host_cmd(&st->core, 0);
		if (ret)
			break;

		/* Save values */
		st->core.calib[0].offset =
			st->core.resp->sensor_offset.offset[0];

		*val = st->core.calib[idx].offset;
		ret = IIO_VAL_INT;
		break;
	case IIO_CHAN_INFO_CALIBSCALE:
		/*
		 * RANGE is used for calibration
		 * scale is a number x.y, where x is coded on 16 bits,
		 * y coded on 16 bits, between 0 and 9999.
		 */
		st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
		st->core.param.sensor_range.data = EC_MOTION_SENSE_NO_VALUE;

		ret = cros_ec_motion_send_host_cmd(&st->core, 0);
		if (ret)
			break;

		val64 = st->core.resp->sensor_range.ret;
		*val = val64 >> 16;
		*val2 = (val64 & 0xffff) * 100;
		ret = IIO_VAL_INT_PLUS_MICRO;
		break;
	default:
		ret = cros_ec_sensors_core_read(&st->core, chan, val, val2,
						mask);
		break;
	}

	mutex_unlock(&st->core.cmd_lock);

Annotation

Implementation Notes