drivers/mfd/mcp-sa11x0.c
Source file repositories/reference/linux-study-clean/drivers/mfd/mcp-sa11x0.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mfd/mcp-sa11x0.c- Extension
.c- Size
- 6960 bytes
- Lines
- 305
- Domain
- Driver Families
- Bucket
- drivers/mfd
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/io.hlinux/errno.hlinux/kernel.hlinux/delay.hlinux/spinlock.hlinux/platform_device.hlinux/pm.hlinux/mfd/mcp.hmach/hardware.hasm/mach-types.hlinux/platform_data/mfd-mcp-sa11x0.h
Detected Declarations
struct mcp_sa11x0function mcp_sa11x0_set_telecom_divisorfunction mcp_sa11x0_set_audio_divisorfunction timesfunction timesfunction mcp_sa11x0_enablefunction mcp_sa11x0_disablefunction mcp_sa11x0_probefunction mcp_sa11x0_removefunction mcp_sa11x0_suspendfunction mcp_sa11x0_resume
Annotated Snippet
struct mcp_sa11x0 {
void __iomem *base0;
void __iomem *base1;
u32 mccr0;
u32 mccr1;
};
/* Register offsets */
#define MCCR0(m) ((m)->base0 + 0x00)
#define MCDR0(m) ((m)->base0 + 0x08)
#define MCDR1(m) ((m)->base0 + 0x0c)
#define MCDR2(m) ((m)->base0 + 0x10)
#define MCSR(m) ((m)->base0 + 0x18)
#define MCCR1(m) ((m)->base1 + 0x00)
#define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp))
static void
mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
{
struct mcp_sa11x0 *m = priv(mcp);
divisor /= 32;
m->mccr0 &= ~0x00007f00;
m->mccr0 |= divisor << 8;
writel_relaxed(m->mccr0, MCCR0(m));
}
static void
mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
{
struct mcp_sa11x0 *m = priv(mcp);
divisor /= 32;
m->mccr0 &= ~0x0000007f;
m->mccr0 |= divisor;
writel_relaxed(m->mccr0, MCCR0(m));
}
/*
* Write data to the device. The bit should be set after 3 subframe
* times (each frame is 64 clocks). We wait a maximum of 6 subframes.
* We really should try doing something more productive while we
* wait.
*/
static void
mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
{
struct mcp_sa11x0 *m = priv(mcp);
int ret = -ETIME;
int i;
writel_relaxed(reg << 17 | MCDR2_Wr | (val & 0xffff), MCDR2(m));
for (i = 0; i < 2; i++) {
udelay(mcp->rw_timeout);
if (readl_relaxed(MCSR(m)) & MCSR_CWC) {
ret = 0;
break;
}
}
if (ret < 0)
printk(KERN_WARNING "mcp: write timed out\n");
}
/*
* Read data from the device. The bit should be set after 3 subframe
* times (each frame is 64 clocks). We wait a maximum of 6 subframes.
* We really should try doing something more productive while we
* wait.
*/
static unsigned int
mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
{
struct mcp_sa11x0 *m = priv(mcp);
int ret = -ETIME;
int i;
writel_relaxed(reg << 17 | MCDR2_Rd, MCDR2(m));
for (i = 0; i < 2; i++) {
udelay(mcp->rw_timeout);
if (readl_relaxed(MCSR(m)) & MCSR_CRC) {
ret = readl_relaxed(MCDR2(m)) & 0xffff;
break;
}
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/io.h`, `linux/errno.h`, `linux/kernel.h`, `linux/delay.h`, `linux/spinlock.h`, `linux/platform_device.h`, `linux/pm.h`.
- Detected declarations: `struct mcp_sa11x0`, `function mcp_sa11x0_set_telecom_divisor`, `function mcp_sa11x0_set_audio_divisor`, `function times`, `function times`, `function mcp_sa11x0_enable`, `function mcp_sa11x0_disable`, `function mcp_sa11x0_probe`, `function mcp_sa11x0_remove`, `function mcp_sa11x0_suspend`.
- Atlas domain: Driver Families / drivers/mfd.
- 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.