drivers/misc/lis3lv02d/lis3lv02d.c
Source file repositories/reference/linux-study-clean/drivers/misc/lis3lv02d/lis3lv02d.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/misc/lis3lv02d/lis3lv02d.c- Extension
.c- Size
- 33956 bytes
- Lines
- 1260
- Domain
- Driver Families
- Bucket
- drivers/misc
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/kernel.hlinux/sched/signal.hlinux/dmi.hlinux/minmax.hlinux/module.hlinux/types.hlinux/interrupt.hlinux/input.hlinux/delay.hlinux/wait.hlinux/poll.hlinux/slab.hlinux/freezer.hlinux/uaccess.hlinux/miscdevice.hlinux/pm_runtime.hlinux/atomic.hlinux/of.hlis3lv02d.h
Detected Declarations
function param_set_axisfunction lis3lv02d_read_8function lis3lv02d_read_12function lis331dlh_read_datafunction lis3lv02d_get_axisfunction lis3lv02d_get_xyzfunction lis3lv02d_get_odr_indexfunction lis3lv02d_get_pwron_waitfunction lis3lv02d_set_odrfunction lis3lv02d_selftestfunction lis3_context_savefunction lis3_context_restorefunction lis3lv02d_powerofffunction lis3lv02d_poweronfunction lis3lv02d_joystick_pollfunction lis3lv02d_joystick_openfunction lis3lv02d_joystick_closefunction lis302dl_interruptfunction lis302dl_interrupt_handle_clickfunction lis302dl_data_readyfunction lis302dl_interrupt_thread1_8bfunction lis302dl_interrupt_thread2_8bfunction lis3lv02d_misc_openfunction lis3lv02d_misc_releasefunction lis3lv02d_misc_readfunction lis3lv02d_misc_pollfunction lis3lv02d_misc_fasyncfunction lis3lv02d_joystick_enablefunction lis3lv02d_joystick_disablefunction lis3lv02d_sysfs_poweronfunction lis3lv02d_selftest_showfunction lis3lv02d_position_showfunction lis3lv02d_rate_showfunction lis3lv02d_rate_setfunction lis3lv02d_add_fsfunction lis3lv02d_remove_fsfunction lis3lv02d_8b_configurefunction lis3lv02d_init_dtfunction lis3lv02d_init_dtfunction lis3lv02d_init_deviceexport lis3_devexport lis3lv02d_poweroffexport lis3lv02d_poweronexport lis3lv02d_joystick_enableexport lis3lv02d_joystick_disableexport lis3lv02d_remove_fsexport lis3lv02d_init_dtexport lis3lv02d_init_device
Annotated Snippet
static const struct file_operations lis3lv02d_misc_fops = {
.owner = THIS_MODULE,
.read = lis3lv02d_misc_read,
.open = lis3lv02d_misc_open,
.release = lis3lv02d_misc_release,
.poll = lis3lv02d_misc_poll,
.fasync = lis3lv02d_misc_fasync,
};
int lis3lv02d_joystick_enable(struct lis3lv02d *lis3)
{
struct input_dev *input_dev;
int err;
int max_val, fuzz, flat;
int btns[] = {BTN_X, BTN_Y, BTN_Z};
if (lis3->idev)
return -EINVAL;
input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM;
input_dev->name = "ST LIS3LV02DL Accelerometer";
input_dev->phys = DRIVER_NAME "/input0";
input_dev->id.bustype = BUS_HOST;
input_dev->id.vendor = 0;
input_dev->dev.parent = &lis3->fdev->dev;
input_dev->open = lis3lv02d_joystick_open;
input_dev->close = lis3lv02d_joystick_close;
max_val = (lis3->mdps_max_val * lis3->scale) / LIS3_ACCURACY;
if (lis3->whoami == WAI_12B) {
fuzz = LIS3_DEFAULT_FUZZ_12B;
flat = LIS3_DEFAULT_FLAT_12B;
} else {
fuzz = LIS3_DEFAULT_FUZZ_8B;
flat = LIS3_DEFAULT_FLAT_8B;
}
fuzz = (fuzz * lis3->scale) / LIS3_ACCURACY;
flat = (flat * lis3->scale) / LIS3_ACCURACY;
input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);
input_set_drvdata(input_dev, lis3);
lis3->idev = input_dev;
err = input_setup_polling(input_dev, lis3lv02d_joystick_poll);
if (err)
goto err_free_input;
input_set_poll_interval(input_dev, MDPS_POLL_INTERVAL);
input_set_min_poll_interval(input_dev, MDPS_POLL_MIN);
input_set_max_poll_interval(input_dev, MDPS_POLL_MAX);
lis3->mapped_btns[0] = lis3lv02d_get_axis(abs(lis3->ac.x), btns);
lis3->mapped_btns[1] = lis3lv02d_get_axis(abs(lis3->ac.y), btns);
lis3->mapped_btns[2] = lis3lv02d_get_axis(abs(lis3->ac.z), btns);
err = input_register_device(lis3->idev);
if (err)
goto err_free_input;
return 0;
err_free_input:
input_free_device(input_dev);
lis3->idev = NULL;
return err;
}
EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable);
void lis3lv02d_joystick_disable(struct lis3lv02d *lis3)
{
if (lis3->irq)
free_irq(lis3->irq, lis3);
if (lis3->pdata && lis3->pdata->irq2)
free_irq(lis3->pdata->irq2, lis3);
if (!lis3->idev)
return;
if (lis3->irq)
misc_deregister(&lis3->miscdev);
input_unregister_device(lis3->idev);
lis3->idev = NULL;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/sched/signal.h`, `linux/dmi.h`, `linux/minmax.h`, `linux/module.h`, `linux/types.h`, `linux/interrupt.h`, `linux/input.h`.
- Detected declarations: `function param_set_axis`, `function lis3lv02d_read_8`, `function lis3lv02d_read_12`, `function lis331dlh_read_data`, `function lis3lv02d_get_axis`, `function lis3lv02d_get_xyz`, `function lis3lv02d_get_odr_index`, `function lis3lv02d_get_pwron_wait`, `function lis3lv02d_set_odr`, `function lis3lv02d_selftest`.
- Atlas domain: Driver Families / drivers/misc.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.