1 /* 2 * rtc-ds1390.c -- driver for the Dallas/Maxim DS1390/93/94 SPI RTC 3 * 4 * Copyright (C) 2008 Mercury IMC Ltd 5 * Written by Mark Jackson <mpfj@mimc.co.uk> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * NOTE: Currently this driver only supports the bare minimum for read 12 * and write the RTC. The extra features provided by the chip family 13 * (alarms, trickle charger, different control registers) are unavailable. 14 */ 15 16 #include <linux/init.h> 17 #include <linux/module.h> 18 #include <linux/platform_device.h> 19 #include <linux/rtc.h> 20 #include <linux/spi/spi.h> 21 #include <linux/bcd.h> 22 #include <linux/slab.h> 23 #include <linux/of.h> 24 25 #define DS1390_REG_100THS 0x00 26 #define DS1390_REG_SECONDS 0x01 27 #define DS1390_REG_MINUTES 0x02 28 #define DS1390_REG_HOURS 0x03 29 #define DS1390_REG_DAY 0x04 30 #define DS1390_REG_DATE 0x05 31 #define DS1390_REG_MONTH_CENT 0x06 32 #define DS1390_REG_YEAR 0x07 33 34 #define DS1390_REG_ALARM_100THS 0x08 35 #define DS1390_REG_ALARM_SECONDS 0x09 36 #define DS1390_REG_ALARM_MINUTES 0x0A 37 #define DS1390_REG_ALARM_HOURS 0x0B 38 #define DS1390_REG_ALARM_DAY_DATE 0x0C 39 40 #define DS1390_REG_CONTROL 0x0D 41 #define DS1390_REG_STATUS 0x0E 42 #define DS1390_REG_TRICKLE 0x0F 43 44 #define DS1390_TRICKLE_CHARGER_ENABLE 0xA0 45 #define DS1390_TRICKLE_CHARGER_250_OHM 0x01 46 #define DS1390_TRICKLE_CHARGER_2K_OHM 0x02 47 #define DS1390_TRICKLE_CHARGER_4K_OHM 0x03 48 #define DS1390_TRICKLE_CHARGER_NO_DIODE 0x04 49 #define DS1390_TRICKLE_CHARGER_DIODE 0x08 50 51 struct ds1390 { 52 struct rtc_device *rtc; 53 u8 txrx_buf[9]; /* cmd + 8 registers */ 54 }; 55 56 static void ds1390_set_reg(struct device *dev, unsigned char address, 57 unsigned char data) 58 { 59 struct spi_device *spi = to_spi_device(dev); 60 unsigned char buf[2]; 61 62 /* MSB must be '1' to write */ 63 buf[0] = address | 0x80; 64 buf[1] = data; 65 66 spi_write(spi, buf, 2); 67 } 68 69 static int ds1390_get_reg(struct device *dev, unsigned char address, 70 unsigned char *data) 71 { 72 struct spi_device *spi = to_spi_device(dev); 73 struct ds1390 *chip = dev_get_drvdata(dev); 74 int status; 75 76 if (!data) 77 return -EINVAL; 78 79 /* Clear MSB to indicate read */ 80 chip->txrx_buf[0] = address & 0x7f; 81 /* do the i/o */ 82 status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 1); 83 if (status != 0) 84 return status; 85 86 *data = chip->txrx_buf[0]; 87 88 return 0; 89 } 90 91 static void ds1390_trickle_of_init(struct spi_device *spi) 92 { 93 u32 ohms = 0; 94 u8 value; 95 96 if (of_property_read_u32(spi->dev.of_node, "trickle-resistor-ohms", 97 &ohms)) 98 goto out; 99 100 /* Enable charger */ 101 value = DS1390_TRICKLE_CHARGER_ENABLE; 102 if (of_property_read_bool(spi->dev.of_node, "trickle-diode-disable")) 103 value |= DS1390_TRICKLE_CHARGER_NO_DIODE; 104 else 105 value |= DS1390_TRICKLE_CHARGER_DIODE; 106 107 /* Resistor select */ 108 switch (ohms) { 109 case 250: 110 value |= DS1390_TRICKLE_CHARGER_250_OHM; 111 break; 112 case 2000: 113 value |= DS1390_TRICKLE_CHARGER_2K_OHM; 114 break; 115 case 4000: 116 value |= DS1390_TRICKLE_CHARGER_4K_OHM; 117 break; 118 default: 119 dev_warn(&spi->dev, 120 "Unsupported ohm value %02ux in dt\n", ohms); 121 return; 122 } 123 124 ds1390_set_reg(&spi->dev, DS1390_REG_TRICKLE, value); 125 126 out: 127 return; 128 } 129 130 static int ds1390_read_time(struct device *dev, struct rtc_time *dt) 131 { 132 struct spi_device *spi = to_spi_device(dev); 133 struct ds1390 *chip = dev_get_drvdata(dev); 134 int status; 135 136 /* build the message */ 137 chip->txrx_buf[0] = DS1390_REG_SECONDS; 138 139 /* do the i/o */ 140 status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 8); 141 if (status != 0) 142 return status; 143 144 /* The chip sends data in this order: 145 * Seconds, Minutes, Hours, Day, Date, Month / Century, Year */ 146 dt->tm_sec = bcd2bin(chip->txrx_buf[0]); 147 dt->tm_min = bcd2bin(chip->txrx_buf[1]); 148 dt->tm_hour = bcd2bin(chip->txrx_buf[2]); 149 dt->tm_wday = bcd2bin(chip->txrx_buf[3]); 150 dt->tm_mday = bcd2bin(chip->txrx_buf[4]); 151 /* mask off century bit */ 152 dt->tm_mon = bcd2bin(chip->txrx_buf[5] & 0x7f) - 1; 153 /* adjust for century bit */ 154 dt->tm_year = bcd2bin(chip->txrx_buf[6]) + ((chip->txrx_buf[5] & 0x80) ? 100 : 0); 155 156 return 0; 157 } 158 159 static int ds1390_set_time(struct device *dev, struct rtc_time *dt) 160 { 161 struct spi_device *spi = to_spi_device(dev); 162 struct ds1390 *chip = dev_get_drvdata(dev); 163 164 /* build the message */ 165 chip->txrx_buf[0] = DS1390_REG_SECONDS | 0x80; 166 chip->txrx_buf[1] = bin2bcd(dt->tm_sec); 167 chip->txrx_buf[2] = bin2bcd(dt->tm_min); 168 chip->txrx_buf[3] = bin2bcd(dt->tm_hour); 169 chip->txrx_buf[4] = bin2bcd(dt->tm_wday); 170 chip->txrx_buf[5] = bin2bcd(dt->tm_mday); 171 chip->txrx_buf[6] = bin2bcd(dt->tm_mon + 1) | 172 ((dt->tm_year > 99) ? 0x80 : 0x00); 173 chip->txrx_buf[7] = bin2bcd(dt->tm_year % 100); 174 175 /* do the i/o */ 176 return spi_write_then_read(spi, chip->txrx_buf, 8, NULL, 0); 177 } 178 179 static const struct rtc_class_ops ds1390_rtc_ops = { 180 .read_time = ds1390_read_time, 181 .set_time = ds1390_set_time, 182 }; 183 184 static int ds1390_probe(struct spi_device *spi) 185 { 186 unsigned char tmp; 187 struct ds1390 *chip; 188 int res; 189 190 spi->mode = SPI_MODE_3; 191 spi->bits_per_word = 8; 192 spi_setup(spi); 193 194 chip = devm_kzalloc(&spi->dev, sizeof(*chip), GFP_KERNEL); 195 if (!chip) 196 return -ENOMEM; 197 198 spi_set_drvdata(spi, chip); 199 200 res = ds1390_get_reg(&spi->dev, DS1390_REG_SECONDS, &tmp); 201 if (res != 0) { 202 dev_err(&spi->dev, "unable to read device\n"); 203 return res; 204 } 205 206 if (spi->dev.of_node) 207 ds1390_trickle_of_init(spi); 208 209 chip->rtc = devm_rtc_device_register(&spi->dev, "ds1390", 210 &ds1390_rtc_ops, THIS_MODULE); 211 if (IS_ERR(chip->rtc)) { 212 dev_err(&spi->dev, "unable to register device\n"); 213 res = PTR_ERR(chip->rtc); 214 } 215 216 return res; 217 } 218 219 static const struct of_device_id ds1390_of_match[] = { 220 { .compatible = "dallas,ds1390" }, 221 {} 222 }; 223 MODULE_DEVICE_TABLE(of, ds1390_of_match); 224 225 static struct spi_driver ds1390_driver = { 226 .driver = { 227 .name = "rtc-ds1390", 228 .of_match_table = of_match_ptr(ds1390_of_match), 229 }, 230 .probe = ds1390_probe, 231 }; 232 233 module_spi_driver(ds1390_driver); 234 235 MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver"); 236 MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>"); 237 MODULE_LICENSE("GPL"); 238 MODULE_ALIAS("spi:rtc-ds1390"); 239