drivers/input/rmi4/rmi_smbus.c
Source file repositories/reference/linux-study-clean/drivers/input/rmi4/rmi_smbus.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/rmi4/rmi_smbus.c- Extension
.c- Size
- 11022 bytes
- Lines
- 437
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/delay.hlinux/i2c.hlinux/interrupt.hlinux/kconfig.hlinux/lockdep.hlinux/module.hlinux/pm.hlinux/rmi.hlinux/slab.hrmi_driver.h
Detected Declarations
struct mapping_table_entrystruct rmi_smb_xportfunction rmi_smb_get_versionfunction smb_block_writefunction rmi_smb_get_command_codefunction rmi_smb_write_blockfunction smb_block_readfunction rmi_smb_read_blockfunction rmi_smb_clear_statefunction rmi_smb_enable_smbus_modefunction rmi_smb_resetfunction rmi_smb_probefunction rmi_smb_removefunction rmi_smb_suspendfunction rmi_smb_runtime_suspendfunction rmi_smb_resumefunction rmi_smb_runtime_resume
Annotated Snippet
struct mapping_table_entry {
__le16 rmiaddr;
u8 readcount;
u8 flags;
};
struct rmi_smb_xport {
struct rmi_transport_dev xport;
struct i2c_client *client;
struct mutex page_mutex;
int page;
u8 table_index;
struct mutex mappingtable_mutex;
struct mapping_table_entry mapping_table[RMI_SMB2_MAP_SIZE];
};
static int rmi_smb_get_version(struct rmi_smb_xport *rmi_smb)
{
struct i2c_client *client = rmi_smb->client;
int retval;
/* Check if for SMBus new version device by reading version byte. */
retval = i2c_smbus_read_byte_data(client, SMB_PROTOCOL_VERSION_ADDRESS);
if (retval < 0) {
dev_err(&client->dev, "failed to get SMBus version number!\n");
return retval;
}
return retval + 1;
}
/* SMB block write - wrapper over ic2_smb_write_block */
static int smb_block_write(struct rmi_transport_dev *xport,
u8 commandcode, const void *buf, size_t len)
{
struct rmi_smb_xport *rmi_smb =
container_of(xport, struct rmi_smb_xport, xport);
struct i2c_client *client = rmi_smb->client;
int retval;
retval = i2c_smbus_write_block_data(client, commandcode, len, buf);
rmi_dbg(RMI_DEBUG_XPORT, &client->dev,
"wrote %zd bytes at %#04x: %d (%*ph)\n",
len, commandcode, retval, (int)len, buf);
return retval;
}
/*
* The function to get command code for smbus operations and keeps
* records to the driver mapping table
*/
static int rmi_smb_get_command_code(struct rmi_transport_dev *xport,
u16 rmiaddr, int bytecount, bool isread, u8 *commandcode)
{
struct rmi_smb_xport *rmi_smb =
container_of(xport, struct rmi_smb_xport, xport);
struct mapping_table_entry new_map;
int i;
int retval = 0;
mutex_lock(&rmi_smb->mappingtable_mutex);
for (i = 0; i < RMI_SMB2_MAP_SIZE; i++) {
struct mapping_table_entry *entry = &rmi_smb->mapping_table[i];
if (le16_to_cpu(entry->rmiaddr) == rmiaddr) {
if (isread) {
if (entry->readcount == bytecount)
goto exit;
} else {
if (entry->flags & RMI_SMB2_MAP_FLAGS_WE) {
goto exit;
}
}
}
}
i = rmi_smb->table_index;
rmi_smb->table_index = (i + 1) % RMI_SMB2_MAP_SIZE;
/* constructs mapping table data entry. 4 bytes each entry */
memset(&new_map, 0, sizeof(new_map));
new_map.rmiaddr = cpu_to_le16(rmiaddr);
new_map.readcount = bytecount;
new_map.flags = !isread ? RMI_SMB2_MAP_FLAGS_WE : 0;
retval = smb_block_write(xport, i + 0x80, &new_map, sizeof(new_map));
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/delay.h`, `linux/i2c.h`, `linux/interrupt.h`, `linux/kconfig.h`, `linux/lockdep.h`, `linux/module.h`, `linux/pm.h`.
- Detected declarations: `struct mapping_table_entry`, `struct rmi_smb_xport`, `function rmi_smb_get_version`, `function smb_block_write`, `function rmi_smb_get_command_code`, `function rmi_smb_write_block`, `function smb_block_read`, `function rmi_smb_read_block`, `function rmi_smb_clear_state`, `function rmi_smb_enable_smbus_mode`.
- Atlas domain: Driver Families / drivers/input.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.