drivers/iio/gyro/itg3200_core.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/gyro/itg3200_core.c
Extension
.c
Size
9536 bytes
Lines
419
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

if (ret) {
			mutex_unlock(&st->lock);
			return ret;
		}
		t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1;

		ret = itg3200_write_reg_8(indio_dev,
					  ITG3200_REG_SAMPLE_RATE_DIV,
					  t);

		mutex_unlock(&st->lock);
		return ret;

	default:
		return -EINVAL;
	}
}

/*
 * Reset device and internal registers to the power-up-default settings
 * Use the gyro clock as reference, as suggested by the datasheet
 */
static int itg3200_reset(struct iio_dev *indio_dev)
{
	struct itg3200 *st = iio_priv(indio_dev);
	int ret;

	dev_dbg(&st->i2c->dev, "reset device");

	ret = itg3200_write_reg_8(indio_dev,
			ITG3200_REG_POWER_MANAGEMENT,
			ITG3200_RESET);
	if (ret) {
		dev_err(&st->i2c->dev, "error resetting device");
		goto error_ret;
	}

	/* Wait for PLL (1ms according to datasheet) */
	udelay(1500);

	ret = itg3200_write_reg_8(indio_dev,
			ITG3200_REG_IRQ_CONFIG,
			ITG3200_IRQ_ACTIVE_HIGH |
			ITG3200_IRQ_PUSH_PULL |
			ITG3200_IRQ_LATCH_50US_PULSE |
			ITG3200_IRQ_LATCH_CLEAR_ANY);

	if (ret)
		dev_err(&st->i2c->dev, "error init device");

error_ret:
	return ret;
}

/* itg3200_enable_full_scale() - Disables the digital low pass filter */
static int itg3200_enable_full_scale(struct iio_dev *indio_dev)
{
	u8 val;
	int ret;

	ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &val);
	if (ret)
		goto err_ret;

	val |= ITG3200_DLPF_FS_SEL_2000;
	return itg3200_write_reg_8(indio_dev, ITG3200_REG_DLPF, val);

err_ret:
	return ret;
}

static int itg3200_initial_setup(struct iio_dev *indio_dev)
{
	struct itg3200 *st = iio_priv(indio_dev);
	int ret;
	u8 val;

	ret = itg3200_reset(indio_dev);
	if (ret)
		goto err_ret;

	ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_ADDRESS, &val);
	if (ret)
		goto err_ret;

	if (((val >> 1) & 0x3f) != 0x34) {
		dev_err(&st->i2c->dev, "invalid reg value 0x%02x", val);
		ret = -ENXIO;
		goto err_ret;
	}

Annotation

Implementation Notes