drivers/input/keyboard/sh_keysc.c
Source file repositories/reference/linux-study-clean/drivers/input/keyboard/sh_keysc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/keyboard/sh_keysc.c- Extension
.c- Size
- 7880 bytes
- Lines
- 333
- 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/kernel.hlinux/module.hlinux/interrupt.hlinux/irq.hlinux/delay.hlinux/platform_device.hlinux/input.hlinux/input/sh_keysc.hlinux/bitmap.hlinux/pm_runtime.hlinux/io.hlinux/slab.h
Detected Declarations
struct sh_keysc_privfunction sh_keysc_readfunction sh_keysc_writefunction sh_keysc_level_modefunction sh_keysc_map_dbgfunction sh_keysc_isrfunction sh_keysc_probefunction sh_keysc_removefunction sh_keysc_suspendfunction sh_keysc_resume
Annotated Snippet
struct sh_keysc_priv {
void __iomem *iomem_base;
DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS);
struct input_dev *input;
struct sh_keysc_info pdata;
};
#define KYCR1 0
#define KYCR2 1
#define KYINDR 2
#define KYOUTDR 3
#define KYCR2_IRQ_LEVEL 0x10
#define KYCR2_IRQ_DISABLED 0x00
static unsigned long sh_keysc_read(struct sh_keysc_priv *p, int reg_nr)
{
return ioread16(p->iomem_base + (reg_nr << 2));
}
static void sh_keysc_write(struct sh_keysc_priv *p, int reg_nr,
unsigned long value)
{
iowrite16(value, p->iomem_base + (reg_nr << 2));
}
static void sh_keysc_level_mode(struct sh_keysc_priv *p,
unsigned long keys_set)
{
struct sh_keysc_info *pdata = &p->pdata;
sh_keysc_write(p, KYOUTDR, 0);
sh_keysc_write(p, KYCR2, KYCR2_IRQ_LEVEL | (keys_set << 8));
if (pdata->kycr2_delay)
udelay(pdata->kycr2_delay);
}
static void sh_keysc_map_dbg(struct device *dev, unsigned long *map,
const char *str)
{
int k;
for (k = 0; k < BITS_TO_LONGS(SH_KEYSC_MAXKEYS); k++)
dev_dbg(dev, "%s[%d] 0x%lx\n", str, k, map[k]);
}
static irqreturn_t sh_keysc_isr(int irq, void *dev_id)
{
struct platform_device *pdev = dev_id;
struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
struct sh_keysc_info *pdata = &priv->pdata;
int keyout_nr = sh_keysc_mode[pdata->mode].keyout;
int keyin_nr = sh_keysc_mode[pdata->mode].keyin;
DECLARE_BITMAP(keys, SH_KEYSC_MAXKEYS);
DECLARE_BITMAP(keys0, SH_KEYSC_MAXKEYS);
DECLARE_BITMAP(keys1, SH_KEYSC_MAXKEYS);
unsigned char keyin_set, tmp;
int i, k, n;
dev_dbg(&pdev->dev, "isr!\n");
bitmap_fill(keys1, SH_KEYSC_MAXKEYS);
bitmap_zero(keys0, SH_KEYSC_MAXKEYS);
do {
bitmap_zero(keys, SH_KEYSC_MAXKEYS);
keyin_set = 0;
sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED);
for (i = 0; i < keyout_nr; i++) {
n = keyin_nr * i;
/* drive one KEYOUT pin low, read KEYIN pins */
sh_keysc_write(priv, KYOUTDR, 0xffff ^ (3 << (i * 2)));
udelay(pdata->delay);
tmp = sh_keysc_read(priv, KYINDR);
/* set bit if key press has been detected */
for (k = 0; k < keyin_nr; k++) {
if (tmp & (1 << k))
__set_bit(n + k, keys);
}
/* keep track of which KEYIN bits that have been set */
keyin_set |= tmp ^ ((1 << keyin_nr) - 1);
}
sh_keysc_level_mode(priv, keyin_set);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/interrupt.h`, `linux/irq.h`, `linux/delay.h`, `linux/platform_device.h`, `linux/input.h`, `linux/input/sh_keysc.h`.
- Detected declarations: `struct sh_keysc_priv`, `function sh_keysc_read`, `function sh_keysc_write`, `function sh_keysc_level_mode`, `function sh_keysc_map_dbg`, `function sh_keysc_isr`, `function sh_keysc_probe`, `function sh_keysc_remove`, `function sh_keysc_suspend`, `function sh_keysc_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.