/*
 * rtc-ds1305.c -- driver for DS1305 and DS1306 SPI RTC chips
 *
 * Copyright (C) 2008 David Brownell
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/bcd.h>
#include <linux/slab.h>
#include <linux/rtc.h>
#include <linux/workqueue.h>

#include <linux/spi/spi.h>
#include <linux/spi/ds1305.h>
#include <linux/module.h>


/*
 * Registers ... mask DS1305_WRITE into register address to write,
 * otherwise you're reading it.  All non-bitmask values are BCD.
 */
#define DS1305_WRITE		0x80


/* RTC date/time ... the main special cases are that we:
 *  - Need fancy "hours" encoding in 12hour mode
 *  - Don't rely on the "day-of-week" field (or tm_wday)
 *  - Are a 21st-century clock (2000 <= year < 2100)
 */
#define DS1305_RTC_LEN		7		/* bytes for RTC regs */

#define DS1305_SEC		0x00		/* register addresses */
#define DS1305_MIN		0x01
#define DS1305_HOUR		0x02
#	define DS1305_HR_12		0x40	/* set == 12 hr mode */
#	define DS1305_HR_PM		0x20	/* set == PM (12hr mode) */
#define DS1305_WDAY		0x03
#define DS1305_MDAY		0x04
#define DS1305_MON		0x05
#define DS1305_YEAR		0x06


/* The two alarms have only sec/min/hour/wday fields (ALM_LEN).
 * DS1305_ALM_DISABLE disables a match field (some combos are bad).
 *
 * NOTE that since we don't use WDAY, we limit ourselves to alarms
 * only one day into the future (vs potentially up to a week).
 *
 * NOTE ALSO that while we could generate once-a-second IRQs (UIE), we
 * don't currently support them.  We'd either need to do it only when
 * no alarm is pending (not the standard model), or to use the second
 * alarm (implying that this is a DS1305 not DS1306, *and* that either
 * it's wired up a second IRQ we know, or that INTCN is set)
 */
#define DS1305_ALM_LEN		4		/* bytes for ALM regs */
#define DS1305_ALM_DISABLE	0x80

#define DS1305_ALM0(r)		(0x07 + (r))	/* register addresses */
#define DS1305_ALM1(r)		(0x0b + (r))


/* three control registers */
#define DS1305_CONTROL_LEN	3		/* bytes of control regs */

#define DS1305_CONTROL		0x0f		/* register addresses */
#	define DS1305_nEOSC		0x80	/* low enables oscillator */
#	define DS1305_WP		0x40	/* write protect */
#	define DS1305_INTCN		0x04	/* clear == only int0 used */
#	define DS1306_1HZ		0x04	/* enable 1Hz output */
#	define DS1305_AEI1		0x02	/* enable ALM1 IRQ */
#	define DS1305_AEI0		0x01	/* enable ALM0 IRQ */
#define DS1305_STATUS		0x10
/* status has just AEIx bits, mirrored as IRQFx */
#define DS1305_TRICKLE		0x11
/* trickle bits are defined in <linux/spi/ds1305.h> */

/* a bunch of NVRAM */
#define DS1305_NVRAM_LEN	96		/* bytes of NVRAM */

#define DS1305_NVRAM		0x20		/* register addresses */


struct ds1305 {
	struct spi_device	*spi;
	struct rtc_device	*rtc;

	struct work_struct	work;

	unsigned long		flags;
#define FLAG_EXITING	0

	bool			hr12;
	u8			ctrl[DS1305_CONTROL_LEN];
};


/*----------------------------------------------------------------------*/

/*
 * Utilities ...  tolerate 12-hour AM/PM notation in case of non-Linux
 * software (like a bootloader) which may require it.
 */

static unsigned bcd2hour(u8 bcd)
{
	if (bcd & DS1305_HR_12) {
		unsigned	hour = 0;

		bcd &= ~DS1305_HR_12;
		if (bcd & DS1305_HR_PM) {
			hour = 12;
			bcd &= ~DS1305_HR_PM;
		}
		hour += bcd2bin(bcd);
		return hour - 1;
	}
	return bcd2bin(bcd);
}

static u8 hour2bcd(bool hr12, int hour)
{
	if (hr12) {
		hour++;
		if (hour <= 12)
			return DS1305_HR_12 | bin2bcd(hour);
		hour -= 12;
		return DS1305_HR_12 | DS1305_HR_PM | bin2bcd(hour);
	}
	return bin2bcd(hour);
}

/*----------------------------------------------------------------------*/

/*
 * Interface to RTC framework
 */

static int ds1305_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
	struct ds1305	*ds1305 = dev_get_drvdata(dev);
	u8		buf[2];
	long		err = -EINVAL;

	buf[0] = DS1305_WRITE | DS1305_CONTROL;
	buf[1] = ds1305->ctrl[0];

	if (enabled) {
		if (ds1305->ctrl[0] & DS1305_AEI0)
			goto done;
		buf[1] |= DS1305_AEI0;
	} else {
		if (!(buf[1] & DS1305_AEI0))
			goto done;
		buf[1] &= ~DS1305_AEI0;
	}
	err = spi_write_then_read(ds1305->spi, buf, sizeof buf, NULL, 0);
	if (err >= 0)
		ds1305->ctrl[0] = buf[1];
done:
	return err;

}


/*
 * Get/set of date and time is pretty normal.
 */

static int ds1305_get_time(struct device *dev, struct rtc_time *time)
{
	struct ds1305	*ds1305 = dev_get_drvdata(dev);
	u8		addr = DS1305_SEC;
	u8		buf[DS1305_RTC_LEN];
	int		status;

	/* Use write-then-read to get all the date/time registers
	 * since dma from stack is nonportable
	 */
	status = spi_write_then_read(ds1305->spi, &addr, sizeof addr,
			buf, sizeof buf);
	if (status < 0)
		return status;

	dev_vdbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n",
		"read", buf[0], buf[1], buf[2], buf[3],
		buf[4], buf[5], buf[6]);

	/* Decode the registers */
	time->tm_sec = bcd2bin(buf[DS1305_SEC]);
	time->tm_min = bcd2bin(buf[DS1305_MIN]);
	time->tm_hour = bcd2hour(buf[DS1305_HOUR]);
	time->tm_wday = buf[DS1305_WDAY] - 1;
	time->tm_mday = bcd2bin(buf[DS1305_MDAY]);
	time->tm_mon = bcd2bin(buf[DS1305_MON]) - 1;
	time->tm_year = bcd2bin(buf[DS1305_YEAR]) + 100;

	dev_vdbg(dev, "%s secs=%d, mins=%d, "
		"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
		"read", time->tm_sec, time->tm_min,
		time->tm_hour, time->tm_mday,
		time->tm_mon, time->tm_year, time->tm_wday);

	/* Time may not be set */
	return rtc_valid_tm(time);
}

static int ds1305_set_time(struct device *dev, struct rtc_time *time)
{
	struct ds1305	*ds1305 = dev_get_drvdata(dev);
	u8		buf[1 + DS1305_RTC_LEN];
	u8		*bp = buf;

	dev_vdbg(dev, "%s secs=%d, mins=%d, "
		"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
		"write", time->tm_sec, time->tm_min,
		time->tm_hour, time->tm_mday,
		time->tm_mon, time->tm_year, time->tm_wday);

	/* Write registers starting at the first time/date address. */
	*bp++ = DS1305_WRITE | DS1305_SEC;

	*bp++ = bin2bcd(time->tm_sec);
	*bp++ = bin2bcd(time->tm_min);
	*bp++ = hour2bcd(ds1305->hr12, time->tm_hour);
	*bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1;
	*bp++ = bin2bcd(time->tm_mday);
	*bp++ = bin2bcd(time->tm_mon + 1);
	*bp++ = bin2bcd(time->tm_year - 100);

	dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n",
		"write", buf[1], buf[2], buf[3],
		buf[4], buf[5], buf[6], buf[7]);

	/* use write-then-read since dma from stack is nonportable */
	return spi_write_then_read(ds1305->spi, buf, sizeof buf,
			NULL, 0);
}

/*
 * Get/set of alarm is a bit funky:
 *
 * - First there's the inherent raciness of getting the (partitioned)
 *   status of an alarm that could trigger while we're reading parts
 *   of that status.
 *
 * - Second there's its limited range (we could increase it a bit by
 *   relying on WDAY), which means it will easily roll over.
 *
 * - Third there's the choice of two alarms and alarm signals.
 *   Here we use ALM0 and expect that nINT0 (open drain) is used;
 *   that's the only real option for DS1306 runtime alarms, and is
 *   natural on DS1305.
 *
 * - Fourth, there's also ALM1, and a second interrupt signal:
 *     + On DS1305 ALM1 uses nINT1 (when INTCN=1) else nINT0;
 *     + On DS1306 ALM1 only uses INT1 (an active high pulse)
 *       and it won't work when VCC1 is active.
 *
 *   So to be most general, we should probably set both alarms to the
 *   same value, letting ALM1 be the wakeup event source on DS1306
 *   and handling several wiring options on DS1305.
 *
 * - Fifth, we support the polled mode (as well as possible; why not?)
 *   even when no interrupt line is wired to an IRQ.
 */

/*
 * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
 */
static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
	struct ds1305	*ds1305 = dev_get_drvdata(dev);
	struct spi_device *spi = ds1305->spi;
	u8		addr;
	int		status;
	u8		buf[DS1305_ALM_LEN];

	/* Refresh control register cache BEFORE reading ALM0 registers,
	 * since reading alarm registers acks any pending IRQ.  That
	 * makes returning "pending" status a bit of a lie, but that bit
	 * of EFI status is at best fragile anyway (given IRQ handlers).
	 */
	addr = DS1305_CONTROL;
	status = spi_write_then_read(spi, &addr, sizeof addr,
			ds1305->ctrl, sizeof ds1305->ctrl);
	if (status < 0)
		return status;

	alm->enabled = !!(ds1305->ctrl[0] & DS1305_AEI0);
	alm->pending = !!(ds1305->ctrl[1] & DS1305_AEI0);

	/* get and check ALM0 registers */
	addr = DS1305_ALM0(DS1305_SEC);
	status = spi_write_then_read(spi, &addr, sizeof addr,
			buf, sizeof buf);
	if (status < 0)
		return status;

	dev_vdbg(dev, "%s: %02x %02x %02x %02x\n",
		"alm0 read", buf[DS1305_SEC], buf[DS1305_MIN],
		buf[DS1305_HOUR], buf[DS1305_WDAY]);

	if ((DS1305_ALM_DISABLE & buf[DS1305_SEC])
			|| (DS1305_ALM_DISABLE & buf[DS1305_MIN])
			|| (DS1305_ALM_DISABLE & buf[DS1305_HOUR]))
		return -EIO;

	/* Stuff these values into alm->time and let RTC framework code
	 * fill in the rest ... and also handle rollover to tomorrow when
	 * that's needed.
	 */
	alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]);
	alm->time.tm_min = bcd2bin(buf[DS1305_MIN]);
	alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]);
	alm->time.tm_mday = -1;
	alm->time.tm_mon = -1;
	alm->time.tm_year = -1;
	/* next three fields are unused by Linux */
	alm->time.tm_wday = -1;
	alm->time.tm_mday = -1;
	alm->time.tm_isdst = -1;

	return 0;
}

/*
 * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
 */
static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
	struct ds1305	*ds1305 = dev_get_drvdata(dev);
	struct spi_device *spi = ds1305->spi;
	unsigned long	now, later;
	struct rtc_time	tm;
	int		status;
	u8		buf[1 + DS1305_ALM_LEN];

	/* convert desired alarm to time_t */
	status = rtc_tm_to_time(&alm->time, &later);
	if (status < 0)
		return status;

	/* Read current time as time_t */
	status = ds1305_get_time(dev, &tm);
	if (status < 0)
		return status;
	status = rtc_tm_to_time(&tm, &now);
	if (status < 0)
		return status;

	/* make sure alarm fires within the next 24 hours */
	if (later <= now)
		return -EINVAL;
	if ((later - now) > 24 * 60 * 60)
		return -EDOM;

	/* disable alarm if needed */
	if (ds1305->ctrl[0] & DS1305_AEI0) {
		ds1305->ctrl[0] &= ~DS1305_AEI0;

		buf[0] = DS1305_WRITE | DS1305_CONTROL;
		buf[1] = ds1305->ctrl[0];
		status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0);
		if (status < 0)
			return status;
	}

	/* write alarm */
	buf[0] = DS1305_WRITE | DS1305_ALM0(DS1305_SEC);
	buf[1 + DS1305_SEC] = bin2bcd(alm->time.tm_sec);
	buf[1 + DS1305_MIN] = bin2bcd(alm->time.tm_min);
	buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour);
	buf[1 + DS1305_WDAY] = DS1305_ALM_DISABLE;

	dev_dbg(dev, "%s: %02x %02x %02x %02x\n",
		"alm0 write", buf[1 + DS1305_SEC], buf[1 + DS1305_MIN],
		buf[1 + DS1305_HOUR], buf[1 + DS1305_WDAY]);

	status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);
	if (status < 0)
		return status;

	/* enable alarm if requested */
	if (alm->enabled) {
		ds1305->ctrl[0] |= DS1305_AEI0;

		buf[0] = DS1305_WRITE | DS1305_CONTROL;
		buf[1] = ds1305->ctrl[0];
		status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0);
	}

	return status;
}

#ifdef CONFIG_PROC_FS

static int ds1305_proc(struct device *dev, struct seq_file *seq)
{
	struct ds1305	*ds1305 = dev_get_drvdata(dev);
	char		*diodes = "no";
	char		*resistors = "";

	/* ctrl[2] is treated as read-only; no locking needed */
	if ((ds1305->ctrl[2] & 0xf0) == DS1305_TRICKLE_MAGIC) {
		switch (ds1305->ctrl[2] & 0x0c) {
		case DS1305_TRICKLE_DS2:
			diodes = "2 diodes, ";
			break;
		case DS1305_TRICKLE_DS1:
			diodes = "1 diode, ";
			break;
		default:
			goto done;
		}
		switch (ds1305->ctrl[2] & 0x03) {
		case DS1305_TRICKLE_2K:
			resistors = "2k Ohm";
			break;
		case DS1305_TRICKLE_4K:
			resistors = "4k Ohm";
			break;
		case DS1305_TRICKLE_8K:
			resistors = "8k Ohm";
			break;
		default:
			diodes = "no";
			break;
		}
	}

done:
	return seq_printf(seq,
			"trickle_charge\t: %s%s\n",
			diodes, resistors);
}

#else
#define ds1305_proc	NULL
#endif

static const struct rtc_class_ops ds1305_ops = {
	.read_time	= ds1305_get_time,
	.set_time	= ds1305_set_time,
	.read_alarm	= ds1305_get_alarm,
	.set_alarm	= ds1305_set_alarm,
	.proc		= ds1305_proc,
	.alarm_irq_enable = ds1305_alarm_irq_enable,
};

static void ds1305_work(struct work_struct *work)
{
	struct ds1305	*ds1305 = container_of(work, struct ds1305, work);
	struct mutex	*lock = &ds1305->rtc->ops_lock;
	struct spi_device *spi = ds1305->spi;
	u8		buf[3];
	int		status;

	/* lock to protect ds1305->ctrl */
	mutex_lock(lock);

	/* Disable the IRQ, and clear its status ... for now, we "know"
	 * that if more than one alarm is active, they're in sync.
	 * Note that reading ALM data registers also clears IRQ status.
	 */
	ds1305->ctrl[0] &= ~(DS1305_AEI1 | DS1305_AEI0);
	ds1305->ctrl[1] = 0;

	buf[0] = DS1305_WRITE | DS1305_CONTROL;
	buf[1] = ds1305->ctrl[0];
	buf[2] = 0;

	status = spi_write_then_read(spi, buf, sizeof buf,
			NULL, 0);
	if (status < 0)
		dev_dbg(&spi->dev, "clear irq --> %d\n", status);

	mutex_unlock(lock);

	if (!test_bit(FLAG_EXITING, &ds1305->flags))
		enable_irq(spi->irq);

	rtc_update_irq(ds1305->rtc, 1, RTC_AF | RTC_IRQF);
}

/*
 * This "real" IRQ handler hands off to a workqueue mostly to allow
 * mutex locking for ds1305->ctrl ... unlike I2C, we could issue async
 * I/O requests in IRQ context (to clear the IRQ status).
 */
static irqreturn_t ds1305_irq(int irq, void *p)
{
	struct ds1305		*ds1305 = p;

	disable_irq(irq);
	schedule_work(&ds1305->work);
	return IRQ_HANDLED;
}

/*----------------------------------------------------------------------*/

/*
 * Interface for NVRAM
 */

static void msg_init(struct spi_message *m, struct spi_transfer *x,
		u8 *addr, size_t count, char *tx, char *rx)
{
	spi_message_init(m);
	memset(x, 0, 2 * sizeof(*x));

	x->tx_buf = addr;
	x->len = 1;
	spi_message_add_tail(x, m);

	x++;

	x->tx_buf = tx;
	x->rx_buf = rx;
	x->len = count;
	spi_message_add_tail(x, m);
}

static ssize_t
ds1305_nvram_read(struct file *filp, struct kobject *kobj,
		struct bin_attribute *attr,
		char *buf, loff_t off, size_t count)
{
	struct spi_device	*spi;
	u8			addr;
	struct spi_message	m;
	struct spi_transfer	x[2];
	int			status;

	spi = container_of(kobj, struct spi_device, dev.kobj);

	if (unlikely(off >= DS1305_NVRAM_LEN))
		return 0;
	if (count >= DS1305_NVRAM_LEN)
		count = DS1305_NVRAM_LEN;
	if ((off + count) > DS1305_NVRAM_LEN)
		count = DS1305_NVRAM_LEN - off;
	if (unlikely(!count))
		return count;

	addr = DS1305_NVRAM + off;
	msg_init(&m, x, &addr, count, NULL, buf);

	status = spi_sync(spi, &m);
	if (status < 0)
		dev_err(&spi->dev, "nvram %s error %d\n", "read", status);
	return (status < 0) ? status : count;
}

static ssize_t
ds1305_nvram_write(struct file *filp, struct kobject *kobj,
		struct bin_attribute *attr,
		char *buf, loff_t off, size_t count)
{
	struct spi_device	*spi;
	u8			addr;
	struct spi_message	m;
	struct spi_transfer	x[2];
	int			status;

	spi = container_of(kobj, struct spi_device, dev.kobj);

	if (unlikely(off >= DS1305_NVRAM_LEN))
		return -EFBIG;
	if (count >= DS1305_NVRAM_LEN)
		count = DS1305_NVRAM_LEN;
	if ((off + count) > DS1305_NVRAM_LEN)
		count = DS1305_NVRAM_LEN - off;
	if (unlikely(!count))
		return count;

	addr = (DS1305_WRITE | DS1305_NVRAM) + off;
	msg_init(&m, x, &addr, count, buf, NULL);

	status = spi_sync(spi, &m);
	if (status < 0)
		dev_err(&spi->dev, "nvram %s error %d\n", "write", status);
	return (status < 0) ? status : count;
}

static struct bin_attribute nvram = {
	.attr.name	= "nvram",
	.attr.mode	= S_IRUGO | S_IWUSR,
	.read		= ds1305_nvram_read,
	.write		= ds1305_nvram_write,
	.size		= DS1305_NVRAM_LEN,
};

/*----------------------------------------------------------------------*/

/*
 * Interface to SPI stack
 */

static int ds1305_probe(struct spi_device *spi)
{
	struct ds1305			*ds1305;
	int				status;
	u8				addr, value;
	struct ds1305_platform_data	*pdata = spi->dev.platform_data;
	bool				write_ctrl = false;

	/* Sanity check board setup data.  This may be hooked up
	 * in 3wire mode, but we don't care.  Note that unless
	 * there's an inverter in place, this needs SPI_CS_HIGH!
	 */
	if ((spi->bits_per_word && spi->bits_per_word != 8)
			|| (spi->max_speed_hz > 2000000)
			|| !(spi->mode & SPI_CPHA))
		return -EINVAL;

	/* set up driver data */
	ds1305 = kzalloc(sizeof *ds1305, GFP_KERNEL);
	if (!ds1305)
		return -ENOMEM;
	ds1305->spi = spi;
	spi_set_drvdata(spi, ds1305);

	/* read and cache control registers */
	addr = DS1305_CONTROL;
	status = spi_write_then_read(spi, &addr, sizeof addr,
			ds1305->ctrl, sizeof ds1305->ctrl);
	if (status < 0) {
		dev_dbg(&spi->dev, "can't %s, %d\n",
				"read", status);
		goto fail0;
	}

	dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n",
			"read", ds1305->ctrl[0],
			ds1305->ctrl[1], ds1305->ctrl[2]);

	/* Sanity check register values ... partially compensating for the
	 * fact that SPI has no device handshake.  A pullup on MISO would
	 * make these tests fail; but not all systems will have one.  If
	 * some register is neither 0x00 nor 0xff, a chip is likely there.
	 */
	if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) {
		dev_dbg(&spi->dev, "RTC chip is not present\n");
		status = -ENODEV;
		goto fail0;
	}
	if (ds1305->ctrl[2] == 0)
		dev_dbg(&spi->dev, "chip may not be present\n");

	/* enable writes if needed ... if we were paranoid it would
	 * make sense to enable them only when absolutely necessary.
	 */
	if (ds1305->ctrl[0] & DS1305_WP) {
		u8		buf[2];

		ds1305->ctrl[0] &= ~DS1305_WP;

		buf[0] = DS1305_WRITE | DS1305_CONTROL;
		buf[1] = ds1305->ctrl[0];
		status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);

		dev_dbg(&spi->dev, "clear WP --> %d\n", status);
		if (status < 0)
			goto fail0;
	}

	/* on DS1305, maybe start oscillator; like most low power
	 * oscillators, it may take a second to stabilize
	 */
	if (ds1305->ctrl[0] & DS1305_nEOSC) {
		ds1305->ctrl[0] &= ~DS1305_nEOSC;
		write_ctrl = true;
		dev_warn(&spi->dev, "SET TIME!\n");
	}

	/* ack any pending IRQs */
	if (ds1305->ctrl[1]) {
		ds1305->ctrl[1] = 0;
		write_ctrl = true;
	}

	/* this may need one-time (re)init */
	if (pdata) {
		/* maybe enable trickle charge */
		if (((ds1305->ctrl[2] & 0xf0) != DS1305_TRICKLE_MAGIC)) {
			ds1305->ctrl[2] = DS1305_TRICKLE_MAGIC
						| pdata->trickle;
			write_ctrl = true;
		}

		/* on DS1306, configure 1 Hz signal */
		if (pdata->is_ds1306) {
			if (pdata->en_1hz) {
				if (!(ds1305->ctrl[0] & DS1306_1HZ)) {
					ds1305->ctrl[0] |= DS1306_1HZ;
					write_ctrl = true;
				}
			} else {
				if (ds1305->ctrl[0] & DS1306_1HZ) {
					ds1305->ctrl[0] &= ~DS1306_1HZ;
					write_ctrl = true;
				}
			}
		}
	}

	if (write_ctrl) {
		u8		buf[4];

		buf[0] = DS1305_WRITE | DS1305_CONTROL;
		buf[1] = ds1305->ctrl[0];
		buf[2] = ds1305->ctrl[1];
		buf[3] = ds1305->ctrl[2];
		status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);
		if (status < 0) {
			dev_dbg(&spi->dev, "can't %s, %d\n",
					"write", status);
			goto fail0;
		}

		dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n",
				"write", ds1305->ctrl[0],
				ds1305->ctrl[1], ds1305->ctrl[2]);
	}

	/* see if non-Linux software set up AM/PM mode */
	addr = DS1305_HOUR;
	status = spi_write_then_read(spi, &addr, sizeof addr,
				&value, sizeof value);
	if (status < 0) {
		dev_dbg(&spi->dev, "read HOUR --> %d\n", status);
		goto fail0;
	}

	ds1305->hr12 = (DS1305_HR_12 & value) != 0;
	if (ds1305->hr12)
		dev_dbg(&spi->dev, "AM/PM\n");

	/* register RTC ... from here on, ds1305->ctrl needs locking */
	ds1305->rtc = rtc_device_register("ds1305", &spi->dev,
			&ds1305_ops, THIS_MODULE);
	if (IS_ERR(ds1305->rtc)) {
		status = PTR_ERR(ds1305->rtc);
		dev_dbg(&spi->dev, "register rtc --> %d\n", status);
		goto fail0;
	}

	/* Maybe set up alarm IRQ; be ready to handle it triggering right
	 * away.  NOTE that we don't share this.  The signal is active low,
	 * and we can't ack it before a SPI message delay.  We temporarily
	 * disable the IRQ until it's acked, which lets us work with more
	 * IRQ trigger modes (not all IRQ controllers can do falling edge).
	 */
	if (spi->irq) {
		INIT_WORK(&ds1305->work, ds1305_work);
		status = request_irq(spi->irq, ds1305_irq,
				0, dev_name(&ds1305->rtc->dev), ds1305);
		if (status < 0) {
			dev_dbg(&spi->dev, "request_irq %d --> %d\n",
					spi->irq, status);
			goto fail1;
		}

		device_set_wakeup_capable(&spi->dev, 1);
	}

	/* export NVRAM */
	status = sysfs_create_bin_file(&spi->dev.kobj, &nvram);
	if (status < 0) {
		dev_dbg(&spi->dev, "register nvram --> %d\n", status);
		goto fail2;
	}

	return 0;

fail2:
	free_irq(spi->irq, ds1305);
fail1:
	rtc_device_unregister(ds1305->rtc);
fail0:
	kfree(ds1305);
	return status;
}

static int ds1305_remove(struct spi_device *spi)
{
	struct ds1305 *ds1305 = spi_get_drvdata(spi);

	sysfs_remove_bin_file(&spi->dev.kobj, &nvram);

	/* carefully shut down irq and workqueue, if present */
	if (spi->irq) {
		set_bit(FLAG_EXITING, &ds1305->flags);
		free_irq(spi->irq, ds1305);
		cancel_work_sync(&ds1305->work);
	}

	rtc_device_unregister(ds1305->rtc);
	spi_set_drvdata(spi, NULL);
	kfree(ds1305);
	return 0;
}

static struct spi_driver ds1305_driver = {
	.driver.name	= "rtc-ds1305",
	.driver.owner	= THIS_MODULE,
	.probe		= ds1305_probe,
	.remove		= ds1305_remove,
	/* REVISIT add suspend/resume */
};

module_spi_driver(ds1305_driver);

MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips");
MODULE_LICENSE("GPL");
MODULE_ALIAS("spi:rtc-ds1305");
