drivers/input/misc/twl4030-vibra.c
Source file repositories/reference/linux-study-clean/drivers/input/misc/twl4030-vibra.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/misc/twl4030-vibra.c- Extension
.c- Size
- 5741 bytes
- Lines
- 241
- 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/module.hlinux/jiffies.hlinux/platform_device.hlinux/of.hlinux/workqueue.hlinux/mfd/twl.hlinux/mfd/twl4030-audio.hlinux/input.hlinux/slab.h
Detected Declarations
struct vibra_infofunction vibra_disable_ledsfunction vibra_enablefunction vibra_disablefunction vibra_play_workfunction vibra_playfunction twl4030_vibra_closefunction twl4030_vibra_suspendfunction twl4030_vibra_resumefunction twl4030_vibra_check_coexistfunction twl4030_vibra_probe
Annotated Snippet
struct vibra_info {
struct device *dev;
struct input_dev *input_dev;
struct work_struct play_work;
bool enabled;
int speed;
int direction;
bool coexist;
};
static void vibra_disable_leds(void)
{
u8 reg;
/* Disable LEDA & LEDB, cannot be used with vibra (PWM) */
twl_i2c_read_u8(TWL4030_MODULE_LED, ®, LEDEN);
reg &= ~0x03;
twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg);
}
/* Powers H-Bridge and enables audio clk */
static void vibra_enable(struct vibra_info *info)
{
u8 reg;
twl4030_audio_enable_resource(TWL4030_AUDIO_RES_POWER);
/* turn H-Bridge on */
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
®, TWL4030_REG_VIBRA_CTL);
twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
(reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
twl4030_audio_enable_resource(TWL4030_AUDIO_RES_APLL);
info->enabled = true;
}
static void vibra_disable(struct vibra_info *info)
{
u8 reg;
/* Power down H-Bridge */
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
®, TWL4030_REG_VIBRA_CTL);
twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
(reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
twl4030_audio_disable_resource(TWL4030_AUDIO_RES_APLL);
twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER);
info->enabled = false;
}
static void vibra_play_work(struct work_struct *work)
{
struct vibra_info *info = container_of(work,
struct vibra_info, play_work);
int dir;
int pwm;
u8 reg;
dir = info->direction;
pwm = info->speed;
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
®, TWL4030_REG_VIBRA_CTL);
if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) {
if (!info->enabled)
vibra_enable(info);
/* set vibra rotation direction */
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
®, TWL4030_REG_VIBRA_CTL);
reg = (dir) ? (reg | TWL4030_VIBRA_DIR) :
(reg & ~TWL4030_VIBRA_DIR);
twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
reg, TWL4030_REG_VIBRA_CTL);
/* set PWM, 1 = max, 255 = min */
twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
256 - pwm, TWL4030_REG_VIBRA_SET);
} else {
if (info->enabled)
vibra_disable(info);
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/jiffies.h`, `linux/platform_device.h`, `linux/of.h`, `linux/workqueue.h`, `linux/mfd/twl.h`, `linux/mfd/twl4030-audio.h`, `linux/input.h`.
- Detected declarations: `struct vibra_info`, `function vibra_disable_leds`, `function vibra_enable`, `function vibra_disable`, `function vibra_play_work`, `function vibra_play`, `function twl4030_vibra_close`, `function twl4030_vibra_suspend`, `function twl4030_vibra_resume`, `function twl4030_vibra_check_coexist`.
- 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.