drivers/input/misc/drv2665.c

Source file repositories/reference/linux-study-clean/drivers/input/misc/drv2665.c

File Facts

System
Linux kernel
Corpus path
drivers/input/misc/drv2665.c
Extension
.c
Size
7691 bytes
Lines
311
Domain
Driver Families
Bucket
drivers/input
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 drv2665_data {
	struct input_dev *input_dev;
	struct i2c_client *client;
	struct regmap *regmap;
	struct work_struct work;
	struct regulator *regulator;
};

/* 8kHz Sine wave to stream to the FIFO */
static const u8 drv2665_sine_wave_form[] = {
	0x00, 0x10, 0x20, 0x2e, 0x3c, 0x48, 0x53, 0x5b, 0x61, 0x65, 0x66,
	0x65, 0x61, 0x5b, 0x53, 0x48, 0x3c, 0x2e, 0x20, 0x10,
	0x00, 0xf0, 0xe0, 0xd2, 0xc4, 0xb8, 0xad, 0xa5, 0x9f, 0x9b, 0x9a,
	0x9b, 0x9f, 0xa5, 0xad, 0xb8, 0xc4, 0xd2, 0xe0, 0xf0, 0x00,
};

static const struct reg_default drv2665_reg_defs[] = {
	{ DRV2665_STATUS, 0x02 },
	{ DRV2665_CTRL_1, 0x28 },
	{ DRV2665_CTRL_2, 0x40 },
	{ DRV2665_FIFO, 0x00 },
};

static void drv2665_worker(struct work_struct *work)
{
	struct drv2665_data *haptics =
				container_of(work, struct drv2665_data, work);
	unsigned int read_buf;
	int error;

	error = regmap_read(haptics->regmap, DRV2665_STATUS, &read_buf);
	if (error) {
		dev_err(&haptics->client->dev,
			"Failed to read status: %d\n", error);
		return;
	}

	if (read_buf & DRV2665_FIFO_EMPTY) {
		error = regmap_bulk_write(haptics->regmap,
					  DRV2665_FIFO,
					  drv2665_sine_wave_form,
					  ARRAY_SIZE(drv2665_sine_wave_form));
		if (error) {
			dev_err(&haptics->client->dev,
				"Failed to write FIFO: %d\n", error);
			return;
		}
	}
}

static int drv2665_haptics_play(struct input_dev *input, void *data,
				struct ff_effect *effect)
{
	struct drv2665_data *haptics = input_get_drvdata(input);

	schedule_work(&haptics->work);

	return 0;
}

static void drv2665_close(struct input_dev *input)
{
	struct drv2665_data *haptics = input_get_drvdata(input);
	int error;

	cancel_work_sync(&haptics->work);

	error = regmap_update_bits(haptics->regmap, DRV2665_CTRL_2,
				   DRV2665_STANDBY, DRV2665_STANDBY);
	if (error)
		dev_err(&haptics->client->dev,
			"Failed to enter standby mode: %d\n", error);
}

static const struct reg_sequence drv2665_init_regs[] = {
	{ DRV2665_CTRL_2, 0 | DRV2665_10_MS_IDLE_TOUT },
	{ DRV2665_CTRL_1, DRV2665_25_VPP_GAIN },
};

static int drv2665_init(struct drv2665_data *haptics)
{
	int error;

	error = regmap_register_patch(haptics->regmap,
				      drv2665_init_regs,
				      ARRAY_SIZE(drv2665_init_regs));
	if (error) {
		dev_err(&haptics->client->dev,
			"Failed to write init registers: %d\n",
			error);

Annotation

Implementation Notes