drivers/rtc/rtc-ds1390.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-ds1390.c
Extension
.c
Size
6149 bytes
Lines
243
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

struct ds1390 {
	struct rtc_device *rtc;
	u8 txrx_buf[9];	/* cmd + 8 registers */
};

static void ds1390_set_reg(struct device *dev, unsigned char address,
			   unsigned char data)
{
	struct spi_device *spi = to_spi_device(dev);
	unsigned char buf[2];

	/* MSB must be '1' to write */
	buf[0] = address | 0x80;
	buf[1] = data;

	spi_write(spi, buf, 2);
}

static int ds1390_get_reg(struct device *dev, unsigned char address,
				unsigned char *data)
{
	struct spi_device *spi = to_spi_device(dev);
	struct ds1390 *chip = dev_get_drvdata(dev);
	int status;

	if (!data)
		return -EINVAL;

	/* Clear MSB to indicate read */
	chip->txrx_buf[0] = address & 0x7f;
	/* do the i/o */
	status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 1);
	if (status != 0)
		return status;

	*data = chip->txrx_buf[0];

	return 0;
}

static void ds1390_trickle_of_init(struct spi_device *spi)
{
	u32 ohms = 0;
	u8 value;

	if (of_property_read_u32(spi->dev.of_node, "trickle-resistor-ohms",
				 &ohms))
		goto out;

	/* Enable charger */
	value = DS1390_TRICKLE_CHARGER_ENABLE;
	if (of_property_read_bool(spi->dev.of_node, "trickle-diode-disable"))
		value |= DS1390_TRICKLE_CHARGER_NO_DIODE;
	else
		value |= DS1390_TRICKLE_CHARGER_DIODE;

	/* Resistor select */
	switch (ohms) {
	case 250:
		value |= DS1390_TRICKLE_CHARGER_250_OHM;
		break;
	case 2000:
		value |= DS1390_TRICKLE_CHARGER_2K_OHM;
		break;
	case 4000:
		value |= DS1390_TRICKLE_CHARGER_4K_OHM;
		break;
	default:
		dev_warn(&spi->dev,
			 "Unsupported ohm value %02ux in dt\n", ohms);
		return;
	}

	ds1390_set_reg(&spi->dev, DS1390_REG_TRICKLE, value);

out:
	return;
}

static int ds1390_read_time(struct device *dev, struct rtc_time *dt)
{
	struct spi_device *spi = to_spi_device(dev);
	struct ds1390 *chip = dev_get_drvdata(dev);
	int status;

	/* build the message */
	chip->txrx_buf[0] = DS1390_REG_SECONDS;

	/* do the i/o */
	status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 7);

Annotation

Implementation Notes