drivers/rtc/rtc-mcp795.c

Source file repositories/reference/linux-study-clean/drivers/rtc/rtc-mcp795.c

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-mcp795.c
Extension
.c
Size
11373 bytes
Lines
453
Domain
Driver Families
Bucket
drivers/rtc
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.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * SPI Driver for Microchip MCP795 RTC
 *
 * Copyright (C) Josef Gajdusek <atx@atx.name>
 *
 * based on other Linux RTC drivers
 *
 * Device datasheet:
 * https://ww1.microchip.com/downloads/en/DeviceDoc/22280A.pdf
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/printk.h>
#include <linux/spi/spi.h>
#include <linux/rtc.h>
#include <linux/of.h>
#include <linux/bcd.h>
#include <linux/delay.h>

/* MCP795 Instructions, see datasheet table 3-1 */
#define MCP795_EEREAD	0x03
#define MCP795_EEWRITE	0x02
#define MCP795_EEWRDI	0x04
#define MCP795_EEWREN	0x06
#define MCP795_SRREAD	0x05
#define MCP795_SRWRITE	0x01
#define MCP795_READ	0x13
#define MCP795_WRITE	0x12
#define MCP795_UNLOCK	0x14
#define MCP795_IDWRITE	0x32
#define MCP795_IDREAD	0x33
#define MCP795_CLRWDT	0x44
#define MCP795_CLRRAM	0x54

/* MCP795 RTCC registers, see datasheet table 4-1 */
#define MCP795_REG_SECONDS	0x01
#define MCP795_REG_DAY		0x04
#define MCP795_REG_MONTH	0x06
#define MCP795_REG_CONTROL	0x08
#define MCP795_REG_ALM0_SECONDS	0x0C
#define MCP795_REG_ALM0_DAY	0x0F

#define MCP795_ST_BIT		BIT(7)
#define MCP795_24_BIT		BIT(6)
#define MCP795_LP_BIT		BIT(5)
#define MCP795_EXTOSC_BIT	BIT(3)
#define MCP795_OSCON_BIT	BIT(5)
#define MCP795_ALM0_BIT		BIT(4)
#define MCP795_ALM1_BIT		BIT(5)
#define MCP795_ALM0IF_BIT	BIT(3)
#define MCP795_ALM0C0_BIT	BIT(4)
#define MCP795_ALM0C1_BIT	BIT(5)
#define MCP795_ALM0C2_BIT	BIT(6)

#define SEC_PER_DAY		(24 * 60 * 60)

static int mcp795_rtcc_read(struct device *dev, u8 addr, u8 *buf, u8 count)
{
	struct spi_device *spi = to_spi_device(dev);
	int ret;
	u8 tx[2];

	tx[0] = MCP795_READ;
	tx[1] = addr;
	ret = spi_write_then_read(spi, tx, sizeof(tx), buf, count);

	if (ret)
		dev_err(dev, "Failed reading %d bytes from address %x.\n",
					count, addr);

	return ret;
}

static int mcp795_rtcc_write(struct device *dev, u8 addr, u8 *data, u8 count)
{
	struct spi_device *spi = to_spi_device(dev);
	int ret;
	u8 tx[257];

	tx[0] = MCP795_WRITE;
	tx[1] = addr;
	memcpy(&tx[2], data, count);

	ret = spi_write(spi, tx, 2 + count);

	if (ret)
		dev_err(dev, "Failed to write %d bytes to address %x.\n",

Annotation

Implementation Notes