drivers/input/misc/drv2667.c
Source file repositories/reference/linux-study-clean/drivers/input/misc/drv2667.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/misc/drv2667.c- Extension
.c- Size
- 12251 bytes
- Lines
- 488
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/i2c.hlinux/input.hlinux/module.hlinux/platform_device.hlinux/regmap.hlinux/slab.hlinux/delay.hlinux/regulator/consumer.h
Detected Declarations
struct drv2667_datafunction drv2667_set_waveform_freqfunction drv2667_workerfunction drv2667_haptics_playfunction drv2667_closefunction drv2667_initfunction drv2667_probefunction drv2667_suspendfunction drv2667_resume
Annotated Snippet
struct drv2667_data {
struct input_dev *input_dev;
struct i2c_client *client;
struct regmap *regmap;
struct work_struct work;
struct regulator *regulator;
u32 page;
u32 magnitude;
u32 frequency;
};
static const struct reg_default drv2667_reg_defs[] = {
{ DRV2667_STATUS, 0x02 },
{ DRV2667_CTRL_1, 0x28 },
{ DRV2667_CTRL_2, 0x40 },
{ DRV2667_WV_SEQ_0, 0x00 },
{ DRV2667_WV_SEQ_1, 0x00 },
{ DRV2667_WV_SEQ_2, 0x00 },
{ DRV2667_WV_SEQ_3, 0x00 },
{ DRV2667_WV_SEQ_4, 0x00 },
{ DRV2667_WV_SEQ_5, 0x00 },
{ DRV2667_WV_SEQ_6, 0x00 },
{ DRV2667_WV_SEQ_7, 0x00 },
{ DRV2667_FIFO, 0x00 },
{ DRV2667_PAGE, 0x00 },
};
static int drv2667_set_waveform_freq(struct drv2667_data *haptics)
{
unsigned int read_buf;
int freq;
int error;
/* Per the data sheet:
* Sinusoid Frequency (Hz) = 7.8125 x Frequency
*/
freq = (haptics->frequency * 1000) / 78125;
if (freq <= 0) {
dev_err(&haptics->client->dev,
"ERROR: Frequency calculated to %i\n", freq);
return -EINVAL;
}
error = regmap_read(haptics->regmap, DRV2667_PAGE, &read_buf);
if (error) {
dev_err(&haptics->client->dev,
"Failed to read the page number: %d\n", error);
return -EIO;
}
if (read_buf == DRV2667_PAGE_0 ||
haptics->page != read_buf) {
error = regmap_write(haptics->regmap,
DRV2667_PAGE, haptics->page);
if (error) {
dev_err(&haptics->client->dev,
"Failed to set the page: %d\n", error);
return -EIO;
}
}
error = regmap_write(haptics->regmap, DRV2667_RAM_FREQ, freq);
if (error)
dev_err(&haptics->client->dev,
"Failed to set the frequency: %d\n", error);
/* Reset back to original page */
if (read_buf == DRV2667_PAGE_0 ||
haptics->page != read_buf) {
error = regmap_write(haptics->regmap, DRV2667_PAGE, read_buf);
if (error) {
dev_err(&haptics->client->dev,
"Failed to set the page: %d\n", error);
return -EIO;
}
}
return error;
}
static void drv2667_worker(struct work_struct *work)
{
struct drv2667_data *haptics = container_of(work, struct drv2667_data, work);
int error;
if (haptics->magnitude) {
error = regmap_write(haptics->regmap,
DRV2667_PAGE, haptics->page);
if (error) {
dev_err(&haptics->client->dev,
Annotation
- Immediate include surface: `linux/i2c.h`, `linux/input.h`, `linux/module.h`, `linux/platform_device.h`, `linux/regmap.h`, `linux/slab.h`, `linux/delay.h`, `linux/regulator/consumer.h`.
- Detected declarations: `struct drv2667_data`, `function drv2667_set_waveform_freq`, `function drv2667_worker`, `function drv2667_haptics_play`, `function drv2667_close`, `function drv2667_init`, `function drv2667_probe`, `function drv2667_suspend`, `function drv2667_resume`.
- Atlas domain: Driver Families / drivers/input.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.