drivers/input/touchscreen/bu21029_ts.c
Source file repositories/reference/linux-study-clean/drivers/input/touchscreen/bu21029_ts.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/touchscreen/bu21029_ts.c- Extension
.c- Size
- 15362 bytes
- Lines
- 472
- 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.
- 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/delay.hlinux/gpio/consumer.hlinux/i2c.hlinux/input.hlinux/input/touchscreen.hlinux/interrupt.hlinux/irq.hlinux/module.hlinux/regulator/consumer.hlinux/timer.h
Detected Declarations
struct bu21029_ts_datafunction bu21029_touch_reportfunction bu21029_touch_releasefunction bu21029_touch_soft_irqfunction bu21029_put_chip_in_resetfunction bu21029_start_chipfunction bu21029_stop_chipfunction bu21029_probefunction bu21029_suspendfunction bu21029_resume
Annotated Snippet
struct bu21029_ts_data {
struct i2c_client *client;
struct input_dev *in_dev;
struct timer_list timer;
struct regulator *vdd;
struct gpio_desc *reset_gpios;
u32 x_plate_ohms;
struct touchscreen_properties prop;
};
static void bu21029_touch_report(struct bu21029_ts_data *bu21029, const u8 *buf)
{
u16 x, y, z1, z2;
u32 rz;
s32 max_pressure = input_abs_get_max(bu21029->in_dev, ABS_PRESSURE);
/*
* compose upper 8 and lower 4 bits into a 12bit value:
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
* | ByteH | ByteL |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
* |b07|b06|b05|b04|b03|b02|b01|b00|b07|b06|b05|b04|b03|b02|b01|b00|
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
* |v11|v10|v09|v08|v07|v06|v05|v04|v03|v02|v01|v00| 0 | 0 | 0 | 0 |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
*/
x = (buf[0] << 4) | (buf[1] >> 4);
y = (buf[2] << 4) | (buf[3] >> 4);
z1 = (buf[4] << 4) | (buf[5] >> 4);
z2 = (buf[6] << 4) | (buf[7] >> 4);
if (z1 && z2) {
/*
* calculate Rz (pressure resistance value) by equation:
* Rz = Rx * (x/Q) * ((z2/z1) - 1), where
* Rx is x-plate resistance,
* Q is the touch screen resolution (8bit = 256, 12bit = 4096)
* x, z1, z2 are the measured positions.
*/
rz = z2 - z1;
rz *= x;
rz *= bu21029->x_plate_ohms;
rz /= z1;
rz = DIV_ROUND_CLOSEST(rz, SCALE_12BIT);
if (rz <= max_pressure) {
touchscreen_report_pos(bu21029->in_dev, &bu21029->prop,
x, y, false);
input_report_abs(bu21029->in_dev, ABS_PRESSURE,
max_pressure - rz);
input_report_key(bu21029->in_dev, BTN_TOUCH, 1);
input_sync(bu21029->in_dev);
}
}
}
static void bu21029_touch_release(struct timer_list *t)
{
struct bu21029_ts_data *bu21029 = timer_container_of(bu21029, t,
timer);
input_report_abs(bu21029->in_dev, ABS_PRESSURE, 0);
input_report_key(bu21029->in_dev, BTN_TOUCH, 0);
input_sync(bu21029->in_dev);
}
static irqreturn_t bu21029_touch_soft_irq(int irq, void *data)
{
struct bu21029_ts_data *bu21029 = data;
u8 buf[BUF_LEN];
int error;
/*
* Read touch data and deassert interrupt (will assert again after
* INTVL_TIME + tConv4 for continuous touch)
*/
error = i2c_smbus_read_i2c_block_data(bu21029->client, BU21029_AUTOSCAN,
sizeof(buf), buf);
if (error < 0)
goto out;
bu21029_touch_report(bu21029, buf);
/* reset timer for pen up detection */
mod_timer(&bu21029->timer,
jiffies + msecs_to_jiffies(PEN_UP_TIMEOUT_MS));
out:
return IRQ_HANDLED;
}
Annotation
- Immediate include surface: `linux/delay.h`, `linux/gpio/consumer.h`, `linux/i2c.h`, `linux/input.h`, `linux/input/touchscreen.h`, `linux/interrupt.h`, `linux/irq.h`, `linux/module.h`.
- Detected declarations: `struct bu21029_ts_data`, `function bu21029_touch_report`, `function bu21029_touch_release`, `function bu21029_touch_soft_irq`, `function bu21029_put_chip_in_reset`, `function bu21029_start_chip`, `function bu21029_stop_chip`, `function bu21029_probe`, `function bu21029_suspend`, `function bu21029_resume`.
- Atlas domain: Driver Families / drivers/input.
- Implementation status: source implementation candidate.
- 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.