cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rtc-ds3232.c (17491B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * RTC client/driver for the Maxim/Dallas DS3232/DS3234 Real-Time Clock
      4 *
      5 * Copyright (C) 2009-2011 Freescale Semiconductor.
      6 * Author: Jack Lan <jack.lan@freescale.com>
      7 * Copyright (C) 2008 MIMOMax Wireless Ltd.
      8 */
      9
     10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     11
     12#include <linux/kernel.h>
     13#include <linux/module.h>
     14#include <linux/interrupt.h>
     15#include <linux/i2c.h>
     16#include <linux/spi/spi.h>
     17#include <linux/rtc.h>
     18#include <linux/bcd.h>
     19#include <linux/slab.h>
     20#include <linux/regmap.h>
     21#include <linux/hwmon.h>
     22
     23#define DS3232_REG_SECONDS      0x00
     24#define DS3232_REG_MINUTES      0x01
     25#define DS3232_REG_HOURS        0x02
     26#define DS3232_REG_AMPM         0x02
     27#define DS3232_REG_DAY          0x03
     28#define DS3232_REG_DATE         0x04
     29#define DS3232_REG_MONTH        0x05
     30#define DS3232_REG_CENTURY      0x05
     31#define DS3232_REG_YEAR         0x06
     32#define DS3232_REG_ALARM1       0x07       /* Alarm 1 BASE */
     33#define DS3232_REG_ALARM2       0x0B       /* Alarm 2 BASE */
     34#define DS3232_REG_CR           0x0E       /* Control register */
     35#       define DS3232_REG_CR_nEOSC   0x80
     36#       define DS3232_REG_CR_INTCN   0x04
     37#       define DS3232_REG_CR_A2IE    0x02
     38#       define DS3232_REG_CR_A1IE    0x01
     39
     40#define DS3232_REG_SR           0x0F       /* control/status register */
     41#       define DS3232_REG_SR_OSF     0x80
     42#       define DS3232_REG_SR_BSY     0x04
     43#       define DS3232_REG_SR_A2F     0x02
     44#       define DS3232_REG_SR_A1F     0x01
     45
     46#define DS3232_REG_TEMPERATURE	0x11
     47#define DS3232_REG_SRAM_START   0x14
     48#define DS3232_REG_SRAM_END     0xFF
     49
     50#define DS3232_REG_SRAM_SIZE    236
     51
     52struct ds3232 {
     53	struct device *dev;
     54	struct regmap *regmap;
     55	int irq;
     56	struct rtc_device *rtc;
     57
     58	bool suspended;
     59};
     60
     61static int ds3232_check_rtc_status(struct device *dev)
     62{
     63	struct ds3232 *ds3232 = dev_get_drvdata(dev);
     64	int ret = 0;
     65	int control, stat;
     66
     67	ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
     68	if (ret)
     69		return ret;
     70
     71	if (stat & DS3232_REG_SR_OSF)
     72		dev_warn(dev,
     73				"oscillator discontinuity flagged, "
     74				"time unreliable\n");
     75
     76	stat &= ~(DS3232_REG_SR_OSF | DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
     77
     78	ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat);
     79	if (ret)
     80		return ret;
     81
     82	/* If the alarm is pending, clear it before requesting
     83	 * the interrupt, so an interrupt event isn't reported
     84	 * before everything is initialized.
     85	 */
     86
     87	ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
     88	if (ret)
     89		return ret;
     90
     91	control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
     92	control |= DS3232_REG_CR_INTCN;
     93
     94	return regmap_write(ds3232->regmap, DS3232_REG_CR, control);
     95}
     96
     97static int ds3232_read_time(struct device *dev, struct rtc_time *time)
     98{
     99	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    100	int ret;
    101	u8 buf[7];
    102	unsigned int year, month, day, hour, minute, second;
    103	unsigned int week, twelve_hr, am_pm;
    104	unsigned int century, add_century = 0;
    105
    106	ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_SECONDS, buf, 7);
    107	if (ret)
    108		return ret;
    109
    110	second = buf[0];
    111	minute = buf[1];
    112	hour = buf[2];
    113	week = buf[3];
    114	day = buf[4];
    115	month = buf[5];
    116	year = buf[6];
    117
    118	/* Extract additional information for AM/PM and century */
    119
    120	twelve_hr = hour & 0x40;
    121	am_pm = hour & 0x20;
    122	century = month & 0x80;
    123
    124	/* Write to rtc_time structure */
    125
    126	time->tm_sec = bcd2bin(second);
    127	time->tm_min = bcd2bin(minute);
    128	if (twelve_hr) {
    129		/* Convert to 24 hr */
    130		if (am_pm)
    131			time->tm_hour = bcd2bin(hour & 0x1F) + 12;
    132		else
    133			time->tm_hour = bcd2bin(hour & 0x1F);
    134	} else {
    135		time->tm_hour = bcd2bin(hour);
    136	}
    137
    138	/* Day of the week in linux range is 0~6 while 1~7 in RTC chip */
    139	time->tm_wday = bcd2bin(week) - 1;
    140	time->tm_mday = bcd2bin(day);
    141	/* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */
    142	time->tm_mon = bcd2bin(month & 0x7F) - 1;
    143	if (century)
    144		add_century = 100;
    145
    146	time->tm_year = bcd2bin(year) + add_century;
    147
    148	return 0;
    149}
    150
    151static int ds3232_set_time(struct device *dev, struct rtc_time *time)
    152{
    153	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    154	u8 buf[7];
    155
    156	/* Extract time from rtc_time and load into ds3232*/
    157
    158	buf[0] = bin2bcd(time->tm_sec);
    159	buf[1] = bin2bcd(time->tm_min);
    160	buf[2] = bin2bcd(time->tm_hour);
    161	/* Day of the week in linux range is 0~6 while 1~7 in RTC chip */
    162	buf[3] = bin2bcd(time->tm_wday + 1);
    163	buf[4] = bin2bcd(time->tm_mday); /* Date */
    164	/* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */
    165	buf[5] = bin2bcd(time->tm_mon + 1);
    166	if (time->tm_year >= 100) {
    167		buf[5] |= 0x80;
    168		buf[6] = bin2bcd(time->tm_year - 100);
    169	} else {
    170		buf[6] = bin2bcd(time->tm_year);
    171	}
    172
    173	return regmap_bulk_write(ds3232->regmap, DS3232_REG_SECONDS, buf, 7);
    174}
    175
    176/*
    177 * DS3232 has two alarm, we only use alarm1
    178 * According to linux specification, only support one-shot alarm
    179 * no periodic alarm mode
    180 */
    181static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
    182{
    183	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    184	int control, stat;
    185	int ret;
    186	u8 buf[4];
    187
    188	ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
    189	if (ret)
    190		goto out;
    191	ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
    192	if (ret)
    193		goto out;
    194	ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_ALARM1, buf, 4);
    195	if (ret)
    196		goto out;
    197
    198	alarm->time.tm_sec = bcd2bin(buf[0] & 0x7F);
    199	alarm->time.tm_min = bcd2bin(buf[1] & 0x7F);
    200	alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F);
    201	alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F);
    202
    203	alarm->enabled = !!(control & DS3232_REG_CR_A1IE);
    204	alarm->pending = !!(stat & DS3232_REG_SR_A1F);
    205
    206	ret = 0;
    207out:
    208	return ret;
    209}
    210
    211/*
    212 * linux rtc-module does not support wday alarm
    213 * and only 24h time mode supported indeed
    214 */
    215static int ds3232_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
    216{
    217	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    218	int control, stat;
    219	int ret;
    220	u8 buf[4];
    221
    222	if (ds3232->irq <= 0)
    223		return -EINVAL;
    224
    225	buf[0] = bin2bcd(alarm->time.tm_sec);
    226	buf[1] = bin2bcd(alarm->time.tm_min);
    227	buf[2] = bin2bcd(alarm->time.tm_hour);
    228	buf[3] = bin2bcd(alarm->time.tm_mday);
    229
    230	/* clear alarm interrupt enable bit */
    231	ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
    232	if (ret)
    233		goto out;
    234	control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
    235	ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
    236	if (ret)
    237		goto out;
    238
    239	/* clear any pending alarm flag */
    240	ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
    241	if (ret)
    242		goto out;
    243	stat &= ~(DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
    244	ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat);
    245	if (ret)
    246		goto out;
    247
    248	ret = regmap_bulk_write(ds3232->regmap, DS3232_REG_ALARM1, buf, 4);
    249	if (ret)
    250		goto out;
    251
    252	if (alarm->enabled) {
    253		control |= DS3232_REG_CR_A1IE;
    254		ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
    255	}
    256out:
    257	return ret;
    258}
    259
    260static int ds3232_update_alarm(struct device *dev, unsigned int enabled)
    261{
    262	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    263	int control;
    264	int ret;
    265
    266	ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
    267	if (ret)
    268		return ret;
    269
    270	if (enabled)
    271		/* enable alarm1 interrupt */
    272		control |= DS3232_REG_CR_A1IE;
    273	else
    274		/* disable alarm1 interrupt */
    275		control &= ~(DS3232_REG_CR_A1IE);
    276	ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
    277
    278	return ret;
    279}
    280
    281/*
    282 * Temperature sensor support for ds3232/ds3234 devices.
    283 * A user-initiated temperature conversion is not started by this function,
    284 * so the temperature is updated once every 64 seconds.
    285 */
    286static int ds3232_hwmon_read_temp(struct device *dev, long int *mC)
    287{
    288	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    289	u8 temp_buf[2];
    290	s16 temp;
    291	int ret;
    292
    293	ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_TEMPERATURE, temp_buf,
    294			       sizeof(temp_buf));
    295	if (ret < 0)
    296		return ret;
    297
    298	/*
    299	 * Temperature is represented as a 10-bit code with a resolution of
    300	 * 0.25 degree celsius and encoded in two's complement format.
    301	 */
    302	temp = (temp_buf[0] << 8) | temp_buf[1];
    303	temp >>= 6;
    304	*mC = temp * 250;
    305
    306	return 0;
    307}
    308
    309static umode_t ds3232_hwmon_is_visible(const void *data,
    310				       enum hwmon_sensor_types type,
    311				       u32 attr, int channel)
    312{
    313	if (type != hwmon_temp)
    314		return 0;
    315
    316	switch (attr) {
    317	case hwmon_temp_input:
    318		return 0444;
    319	default:
    320		return 0;
    321	}
    322}
    323
    324static int ds3232_hwmon_read(struct device *dev,
    325			     enum hwmon_sensor_types type,
    326			     u32 attr, int channel, long *temp)
    327{
    328	int err;
    329
    330	switch (attr) {
    331	case hwmon_temp_input:
    332		err = ds3232_hwmon_read_temp(dev, temp);
    333		break;
    334	default:
    335		err = -EOPNOTSUPP;
    336		break;
    337	}
    338
    339	return err;
    340}
    341
    342static u32 ds3232_hwmon_chip_config[] = {
    343	HWMON_C_REGISTER_TZ,
    344	0
    345};
    346
    347static const struct hwmon_channel_info ds3232_hwmon_chip = {
    348	.type = hwmon_chip,
    349	.config = ds3232_hwmon_chip_config,
    350};
    351
    352static u32 ds3232_hwmon_temp_config[] = {
    353	HWMON_T_INPUT,
    354	0
    355};
    356
    357static const struct hwmon_channel_info ds3232_hwmon_temp = {
    358	.type = hwmon_temp,
    359	.config = ds3232_hwmon_temp_config,
    360};
    361
    362static const struct hwmon_channel_info *ds3232_hwmon_info[] = {
    363	&ds3232_hwmon_chip,
    364	&ds3232_hwmon_temp,
    365	NULL
    366};
    367
    368static const struct hwmon_ops ds3232_hwmon_hwmon_ops = {
    369	.is_visible = ds3232_hwmon_is_visible,
    370	.read = ds3232_hwmon_read,
    371};
    372
    373static const struct hwmon_chip_info ds3232_hwmon_chip_info = {
    374	.ops = &ds3232_hwmon_hwmon_ops,
    375	.info = ds3232_hwmon_info,
    376};
    377
    378static void ds3232_hwmon_register(struct device *dev, const char *name)
    379{
    380	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    381	struct device *hwmon_dev;
    382
    383	if (!IS_ENABLED(CONFIG_RTC_DRV_DS3232_HWMON))
    384		return;
    385
    386	hwmon_dev = devm_hwmon_device_register_with_info(dev, name, ds3232,
    387							&ds3232_hwmon_chip_info,
    388							NULL);
    389	if (IS_ERR(hwmon_dev)) {
    390		dev_err(dev, "unable to register hwmon device %ld\n",
    391			PTR_ERR(hwmon_dev));
    392	}
    393}
    394
    395static int ds3232_alarm_irq_enable(struct device *dev, unsigned int enabled)
    396{
    397	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    398
    399	if (ds3232->irq <= 0)
    400		return -EINVAL;
    401
    402	return ds3232_update_alarm(dev, enabled);
    403}
    404
    405static irqreturn_t ds3232_irq(int irq, void *dev_id)
    406{
    407	struct device *dev = dev_id;
    408	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    409	int ret;
    410	int stat, control;
    411
    412	rtc_lock(ds3232->rtc);
    413
    414	ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
    415	if (ret)
    416		goto unlock;
    417
    418	if (stat & DS3232_REG_SR_A1F) {
    419		ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
    420		if (ret) {
    421			dev_warn(ds3232->dev,
    422				 "Read Control Register error %d\n", ret);
    423		} else {
    424			/* disable alarm1 interrupt */
    425			control &= ~(DS3232_REG_CR_A1IE);
    426			ret = regmap_write(ds3232->regmap, DS3232_REG_CR,
    427					   control);
    428			if (ret) {
    429				dev_warn(ds3232->dev,
    430					 "Write Control Register error %d\n",
    431					 ret);
    432				goto unlock;
    433			}
    434
    435			/* clear the alarm pend flag */
    436			stat &= ~DS3232_REG_SR_A1F;
    437			ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat);
    438			if (ret) {
    439				dev_warn(ds3232->dev,
    440					 "Write Status Register error %d\n",
    441					 ret);
    442				goto unlock;
    443			}
    444
    445			rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF);
    446		}
    447	}
    448
    449unlock:
    450	rtc_unlock(ds3232->rtc);
    451
    452	return IRQ_HANDLED;
    453}
    454
    455static const struct rtc_class_ops ds3232_rtc_ops = {
    456	.read_time = ds3232_read_time,
    457	.set_time = ds3232_set_time,
    458	.read_alarm = ds3232_read_alarm,
    459	.set_alarm = ds3232_set_alarm,
    460	.alarm_irq_enable = ds3232_alarm_irq_enable,
    461};
    462
    463static int ds3232_nvmem_read(void *priv, unsigned int offset, void *val,
    464			     size_t bytes)
    465{
    466	struct regmap *ds3232_regmap = (struct regmap *)priv;
    467
    468	return regmap_bulk_read(ds3232_regmap, DS3232_REG_SRAM_START + offset,
    469				val, bytes);
    470}
    471
    472static int ds3232_nvmem_write(void *priv, unsigned int offset, void *val,
    473			      size_t bytes)
    474{
    475	struct regmap *ds3232_regmap = (struct regmap *)priv;
    476
    477	return regmap_bulk_write(ds3232_regmap, DS3232_REG_SRAM_START + offset,
    478				 val, bytes);
    479}
    480
    481static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
    482			const char *name)
    483{
    484	struct ds3232 *ds3232;
    485	int ret;
    486	struct nvmem_config nvmem_cfg = {
    487		.name = "ds3232_sram",
    488		.stride = 1,
    489		.size = DS3232_REG_SRAM_SIZE,
    490		.word_size = 1,
    491		.reg_read = ds3232_nvmem_read,
    492		.reg_write = ds3232_nvmem_write,
    493		.priv = regmap,
    494		.type = NVMEM_TYPE_BATTERY_BACKED
    495	};
    496
    497	ds3232 = devm_kzalloc(dev, sizeof(*ds3232), GFP_KERNEL);
    498	if (!ds3232)
    499		return -ENOMEM;
    500
    501	ds3232->regmap = regmap;
    502	ds3232->irq = irq;
    503	ds3232->dev = dev;
    504	dev_set_drvdata(dev, ds3232);
    505
    506	ret = ds3232_check_rtc_status(dev);
    507	if (ret)
    508		return ret;
    509
    510	if (ds3232->irq > 0)
    511		device_init_wakeup(dev, 1);
    512
    513	ds3232_hwmon_register(dev, name);
    514
    515	ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops,
    516						THIS_MODULE);
    517	if (IS_ERR(ds3232->rtc))
    518		return PTR_ERR(ds3232->rtc);
    519
    520	ret = devm_rtc_nvmem_register(ds3232->rtc, &nvmem_cfg);
    521	if(ret)
    522		return ret;
    523
    524	if (ds3232->irq > 0) {
    525		ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
    526						ds3232_irq,
    527						IRQF_SHARED | IRQF_ONESHOT,
    528						name, dev);
    529		if (ret) {
    530			device_set_wakeup_capable(dev, 0);
    531			ds3232->irq = 0;
    532			dev_err(dev, "unable to request IRQ\n");
    533		}
    534	}
    535
    536	return 0;
    537}
    538
    539#ifdef CONFIG_PM_SLEEP
    540static int ds3232_suspend(struct device *dev)
    541{
    542	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    543
    544	if (device_may_wakeup(dev)) {
    545		if (enable_irq_wake(ds3232->irq))
    546			dev_warn_once(dev, "Cannot set wakeup source\n");
    547	}
    548
    549	return 0;
    550}
    551
    552static int ds3232_resume(struct device *dev)
    553{
    554	struct ds3232 *ds3232 = dev_get_drvdata(dev);
    555
    556	if (device_may_wakeup(dev))
    557		disable_irq_wake(ds3232->irq);
    558
    559	return 0;
    560}
    561#endif
    562
    563static const struct dev_pm_ops ds3232_pm_ops = {
    564	SET_SYSTEM_SLEEP_PM_OPS(ds3232_suspend, ds3232_resume)
    565};
    566
    567#if IS_ENABLED(CONFIG_I2C)
    568
    569static int ds3232_i2c_probe(struct i2c_client *client,
    570			    const struct i2c_device_id *id)
    571{
    572	struct regmap *regmap;
    573	static const struct regmap_config config = {
    574		.reg_bits = 8,
    575		.val_bits = 8,
    576		.max_register = DS3232_REG_SRAM_END,
    577	};
    578
    579	regmap = devm_regmap_init_i2c(client, &config);
    580	if (IS_ERR(regmap)) {
    581		dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
    582			__func__, PTR_ERR(regmap));
    583		return PTR_ERR(regmap);
    584	}
    585
    586	return ds3232_probe(&client->dev, regmap, client->irq, client->name);
    587}
    588
    589static const struct i2c_device_id ds3232_id[] = {
    590	{ "ds3232", 0 },
    591	{ }
    592};
    593MODULE_DEVICE_TABLE(i2c, ds3232_id);
    594
    595static const  __maybe_unused struct of_device_id ds3232_of_match[] = {
    596	{ .compatible = "dallas,ds3232" },
    597	{ }
    598};
    599MODULE_DEVICE_TABLE(of, ds3232_of_match);
    600
    601static struct i2c_driver ds3232_driver = {
    602	.driver = {
    603		.name = "rtc-ds3232",
    604		.of_match_table = of_match_ptr(ds3232_of_match),
    605		.pm	= &ds3232_pm_ops,
    606	},
    607	.probe = ds3232_i2c_probe,
    608	.id_table = ds3232_id,
    609};
    610
    611static int ds3232_register_driver(void)
    612{
    613	return i2c_add_driver(&ds3232_driver);
    614}
    615
    616static void ds3232_unregister_driver(void)
    617{
    618	i2c_del_driver(&ds3232_driver);
    619}
    620
    621#else
    622
    623static int ds3232_register_driver(void)
    624{
    625	return 0;
    626}
    627
    628static void ds3232_unregister_driver(void)
    629{
    630}
    631
    632#endif
    633
    634#if IS_ENABLED(CONFIG_SPI_MASTER)
    635
    636static int ds3234_probe(struct spi_device *spi)
    637{
    638	int res;
    639	unsigned int tmp;
    640	static const struct regmap_config config = {
    641		.reg_bits = 8,
    642		.val_bits = 8,
    643		.max_register = DS3232_REG_SRAM_END,
    644		.write_flag_mask = 0x80,
    645	};
    646	struct regmap *regmap;
    647
    648	regmap = devm_regmap_init_spi(spi, &config);
    649	if (IS_ERR(regmap)) {
    650		dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
    651			__func__, PTR_ERR(regmap));
    652		return PTR_ERR(regmap);
    653	}
    654
    655	spi->mode = SPI_MODE_3;
    656	spi->bits_per_word = 8;
    657	spi_setup(spi);
    658
    659	res = regmap_read(regmap, DS3232_REG_SECONDS, &tmp);
    660	if (res)
    661		return res;
    662
    663	/* Control settings
    664	 *
    665	 * CONTROL_REG
    666	 * BIT 7	6	5	4	3	2	1	0
    667	 *     EOSC	BBSQW	CONV	RS2	RS1	INTCN	A2IE	A1IE
    668	 *
    669	 *     0	0	0	1	1	1	0	0
    670	 *
    671	 * CONTROL_STAT_REG
    672	 * BIT 7	6	5	4	3	2	1	0
    673	 *     OSF	BB32kHz	CRATE1	CRATE0	EN32kHz	BSY	A2F	A1F
    674	 *
    675	 *     1	0	0	0	1	0	0	0
    676	 */
    677	res = regmap_read(regmap, DS3232_REG_CR, &tmp);
    678	if (res)
    679		return res;
    680	res = regmap_write(regmap, DS3232_REG_CR, tmp & 0x1c);
    681	if (res)
    682		return res;
    683
    684	res = regmap_read(regmap, DS3232_REG_SR, &tmp);
    685	if (res)
    686		return res;
    687	res = regmap_write(regmap, DS3232_REG_SR, tmp & 0x88);
    688	if (res)
    689		return res;
    690
    691	/* Print our settings */
    692	res = regmap_read(regmap, DS3232_REG_CR, &tmp);
    693	if (res)
    694		return res;
    695	dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp);
    696
    697	res = regmap_read(regmap, DS3232_REG_SR, &tmp);
    698	if (res)
    699		return res;
    700	dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
    701
    702	return ds3232_probe(&spi->dev, regmap, spi->irq, "ds3234");
    703}
    704
    705static struct spi_driver ds3234_driver = {
    706	.driver = {
    707		.name	 = "ds3234",
    708	},
    709	.probe	 = ds3234_probe,
    710};
    711
    712static int ds3234_register_driver(void)
    713{
    714	return spi_register_driver(&ds3234_driver);
    715}
    716
    717static void ds3234_unregister_driver(void)
    718{
    719	spi_unregister_driver(&ds3234_driver);
    720}
    721
    722#else
    723
    724static int ds3234_register_driver(void)
    725{
    726	return 0;
    727}
    728
    729static void ds3234_unregister_driver(void)
    730{
    731}
    732
    733#endif
    734
    735static int __init ds323x_init(void)
    736{
    737	int ret;
    738
    739	ret = ds3232_register_driver();
    740	if (ret) {
    741		pr_err("Failed to register ds3232 driver: %d\n", ret);
    742		return ret;
    743	}
    744
    745	ret = ds3234_register_driver();
    746	if (ret) {
    747		pr_err("Failed to register ds3234 driver: %d\n", ret);
    748		ds3232_unregister_driver();
    749	}
    750
    751	return ret;
    752}
    753module_init(ds323x_init)
    754
    755static void __exit ds323x_exit(void)
    756{
    757	ds3234_unregister_driver();
    758	ds3232_unregister_driver();
    759}
    760module_exit(ds323x_exit)
    761
    762MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
    763MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
    764MODULE_DESCRIPTION("Maxim/Dallas DS3232/DS3234 RTC Driver");
    765MODULE_LICENSE("GPL");
    766MODULE_ALIAS("spi:ds3234");