drivers/iio/gyro/adxrs450.c

Source file repositories/reference/linux-study-clean/drivers/iio/gyro/adxrs450.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/gyro/adxrs450.c
Extension
.c
Size
10869 bytes
Lines
460
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 adxrs450_state {
	struct spi_device	*us;
	struct mutex		buf_lock;
	__be32			tx __aligned(IIO_DMA_MINALIGN);
	__be32			rx;

};

/**
 * adxrs450_spi_read_reg_16() - read 2 bytes from a register pair
 * @indio_dev: device associated with child of actual iio_dev
 * @reg_address: the address of the lower of the two registers, which should be
 *	an even address, the second register's address is reg_address + 1.
 * @val: somewhere to pass back the value read
 **/
static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,
				    u8 reg_address,
				    u16 *val)
{
	struct adxrs450_state *st = iio_priv(indio_dev);
	u32 tx;
	int ret;
	struct spi_transfer xfers[] = {
		{
			.tx_buf = &st->tx,
			.len = sizeof(st->tx),
			.cs_change = 1,
		}, {
			.rx_buf = &st->rx,
			.len = sizeof(st->rx),
		},
	};

	mutex_lock(&st->buf_lock);
	tx = ADXRS450_READ_DATA | (reg_address << 17);

	if (!(hweight32(tx) & 1))
		tx |= ADXRS450_P;

	st->tx = cpu_to_be32(tx);
	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
	if (ret) {
		dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n",
				reg_address);
		goto error_ret;
	}

	*val = (be32_to_cpu(st->rx) >> 5) & 0xFFFF;

error_ret:
	mutex_unlock(&st->buf_lock);
	return ret;
}

/**
 * adxrs450_spi_write_reg_16() - write 2 bytes data to a register pair
 * @indio_dev: device associated with child of actual actual iio_dev
 * @reg_address: the address of the lower of the two registers,which should be
 *	an even address, the second register's address is reg_address + 1.
 * @val: value to be written.
 **/
static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev,
				     u8 reg_address,
				     u16 val)
{
	struct adxrs450_state *st = iio_priv(indio_dev);
	u32 tx;
	int ret;

	mutex_lock(&st->buf_lock);
	tx = ADXRS450_WRITE_DATA | (reg_address << 17) | (val << 1);

	if (!(hweight32(tx) & 1))
		tx |= ADXRS450_P;

	st->tx = cpu_to_be32(tx);
	ret = spi_write(st->us, &st->tx, sizeof(st->tx));
	if (ret)
		dev_err(&st->us->dev, "problem while writing 16 bit register 0x%02x\n",
			reg_address);
	usleep_range(100, 1000); /* enforce sequential transfer delay 0.1ms */
	mutex_unlock(&st->buf_lock);
	return ret;
}

/**
 * adxrs450_spi_sensor_data() - read 2 bytes sensor data
 * @indio_dev: device associated with child of actual iio_dev
 * @val: somewhere to pass back the value read
 **/

Annotation

Implementation Notes