18e12ecc2SRaphael Assenat /* drivers/char/max6902.c 28e12ecc2SRaphael Assenat * 38e12ecc2SRaphael Assenat * Copyright (C) 2006 8D Technologies inc. 48e12ecc2SRaphael Assenat * Copyright (C) 2004 Compulab Ltd. 58e12ecc2SRaphael Assenat * 68e12ecc2SRaphael Assenat * This program is free software; you can redistribute it and/or modify 78e12ecc2SRaphael Assenat * it under the terms of the GNU General Public License version 2 as 88e12ecc2SRaphael Assenat * published by the Free Software Foundation. 98e12ecc2SRaphael Assenat * 108e12ecc2SRaphael Assenat * Driver for MAX6902 spi RTC 118e12ecc2SRaphael Assenat * 128e12ecc2SRaphael Assenat * Changelog: 138e12ecc2SRaphael Assenat * 148e12ecc2SRaphael Assenat * 24-May-2006: Raphael Assenat <raph@8d.com> 158e12ecc2SRaphael Assenat * - Major rework 168e12ecc2SRaphael Assenat * Converted to rtc_device and uses the SPI layer. 178e12ecc2SRaphael Assenat * 188e12ecc2SRaphael Assenat * ??-???-2005: Someone at Compulab 198e12ecc2SRaphael Assenat * - Initial driver creation. 208e12ecc2SRaphael Assenat */ 218e12ecc2SRaphael Assenat 228e12ecc2SRaphael Assenat #include <linux/config.h> 238e12ecc2SRaphael Assenat #include <linux/module.h> 248e12ecc2SRaphael Assenat #include <linux/version.h> 258e12ecc2SRaphael Assenat 268e12ecc2SRaphael Assenat #include <linux/kernel.h> 278e12ecc2SRaphael Assenat #include <linux/platform_device.h> 288e12ecc2SRaphael Assenat #include <linux/init.h> 298e12ecc2SRaphael Assenat #include <linux/rtc.h> 308e12ecc2SRaphael Assenat #include <linux/spi/spi.h> 318e12ecc2SRaphael Assenat #include <linux/bcd.h> 328e12ecc2SRaphael Assenat #include <linux/delay.h> 338e12ecc2SRaphael Assenat 348e12ecc2SRaphael Assenat #define MAX6902_REG_SECONDS 0x01 358e12ecc2SRaphael Assenat #define MAX6902_REG_MINUTES 0x03 368e12ecc2SRaphael Assenat #define MAX6902_REG_HOURS 0x05 378e12ecc2SRaphael Assenat #define MAX6902_REG_DATE 0x07 388e12ecc2SRaphael Assenat #define MAX6902_REG_MONTH 0x09 398e12ecc2SRaphael Assenat #define MAX6902_REG_DAY 0x0B 408e12ecc2SRaphael Assenat #define MAX6902_REG_YEAR 0x0D 418e12ecc2SRaphael Assenat #define MAX6902_REG_CONTROL 0x0F 428e12ecc2SRaphael Assenat #define MAX6902_REG_CENTURY 0x13 438e12ecc2SRaphael Assenat 448e12ecc2SRaphael Assenat #undef MAX6902_DEBUG 458e12ecc2SRaphael Assenat 468e12ecc2SRaphael Assenat struct max6902 { 478e12ecc2SRaphael Assenat struct rtc_device *rtc; 488e12ecc2SRaphael Assenat u8 buf[9]; /* Burst read cmd + 8 registers */ 498e12ecc2SRaphael Assenat u8 tx_buf[2]; 508e12ecc2SRaphael Assenat u8 rx_buf[2]; 518e12ecc2SRaphael Assenat }; 528e12ecc2SRaphael Assenat 538e12ecc2SRaphael Assenat static void max6902_set_reg(struct device *dev, unsigned char address, 548e12ecc2SRaphael Assenat unsigned char data) 558e12ecc2SRaphael Assenat { 568e12ecc2SRaphael Assenat struct spi_device *spi = to_spi_device(dev); 578e12ecc2SRaphael Assenat unsigned char buf[2]; 588e12ecc2SRaphael Assenat 598e12ecc2SRaphael Assenat /* MSB must be '0' to write */ 608e12ecc2SRaphael Assenat buf[0] = address & 0x7f; 618e12ecc2SRaphael Assenat buf[1] = data; 628e12ecc2SRaphael Assenat 638e12ecc2SRaphael Assenat spi_write(spi, buf, 2); 648e12ecc2SRaphael Assenat } 658e12ecc2SRaphael Assenat 668e12ecc2SRaphael Assenat static int max6902_get_reg(struct device *dev, unsigned char address, 678e12ecc2SRaphael Assenat unsigned char *data) 688e12ecc2SRaphael Assenat { 698e12ecc2SRaphael Assenat struct spi_device *spi = to_spi_device(dev); 708e12ecc2SRaphael Assenat struct max6902 *chip = dev_get_drvdata(dev); 718e12ecc2SRaphael Assenat struct spi_message message; 728e12ecc2SRaphael Assenat struct spi_transfer xfer; 738e12ecc2SRaphael Assenat int status; 748e12ecc2SRaphael Assenat 758e12ecc2SRaphael Assenat if (!data) 768e12ecc2SRaphael Assenat return -EINVAL; 778e12ecc2SRaphael Assenat 788e12ecc2SRaphael Assenat /* Build our spi message */ 798e12ecc2SRaphael Assenat spi_message_init(&message); 808e12ecc2SRaphael Assenat memset(&xfer, 0, sizeof(xfer)); 818e12ecc2SRaphael Assenat xfer.len = 2; 828e12ecc2SRaphael Assenat /* Can tx_buf and rx_buf be equal? The doc in spi.h is not sure... */ 838e12ecc2SRaphael Assenat xfer.tx_buf = chip->tx_buf; 848e12ecc2SRaphael Assenat xfer.rx_buf = chip->rx_buf; 858e12ecc2SRaphael Assenat 868e12ecc2SRaphael Assenat /* Set MSB to indicate read */ 878e12ecc2SRaphael Assenat chip->tx_buf[0] = address | 0x80; 888e12ecc2SRaphael Assenat 898e12ecc2SRaphael Assenat spi_message_add_tail(&xfer, &message); 908e12ecc2SRaphael Assenat 918e12ecc2SRaphael Assenat /* do the i/o */ 928e12ecc2SRaphael Assenat status = spi_sync(spi, &message); 938e12ecc2SRaphael Assenat if (status == 0) 948e12ecc2SRaphael Assenat status = message.status; 958e12ecc2SRaphael Assenat else 968e12ecc2SRaphael Assenat return status; 978e12ecc2SRaphael Assenat 988e12ecc2SRaphael Assenat *data = chip->rx_buf[1]; 998e12ecc2SRaphael Assenat 1008e12ecc2SRaphael Assenat return status; 1018e12ecc2SRaphael Assenat } 1028e12ecc2SRaphael Assenat 1038e12ecc2SRaphael Assenat static int max6902_get_datetime(struct device *dev, struct rtc_time *dt) 1048e12ecc2SRaphael Assenat { 1058e12ecc2SRaphael Assenat unsigned char tmp; 1068e12ecc2SRaphael Assenat int century; 1078e12ecc2SRaphael Assenat int err; 1088e12ecc2SRaphael Assenat struct spi_device *spi = to_spi_device(dev); 1098e12ecc2SRaphael Assenat struct max6902 *chip = dev_get_drvdata(dev); 1108e12ecc2SRaphael Assenat struct spi_message message; 1118e12ecc2SRaphael Assenat struct spi_transfer xfer; 1128e12ecc2SRaphael Assenat int status; 1138e12ecc2SRaphael Assenat 1148e12ecc2SRaphael Assenat err = max6902_get_reg(dev, MAX6902_REG_CENTURY, &tmp); 1158e12ecc2SRaphael Assenat if (err) 1168e12ecc2SRaphael Assenat return err; 1178e12ecc2SRaphael Assenat 1188e12ecc2SRaphael Assenat /* build the message */ 1198e12ecc2SRaphael Assenat spi_message_init(&message); 1208e12ecc2SRaphael Assenat memset(&xfer, 0, sizeof(xfer)); 1218e12ecc2SRaphael Assenat xfer.len = 1 + 7; /* Burst read command + 7 registers */ 1228e12ecc2SRaphael Assenat xfer.tx_buf = chip->buf; 1238e12ecc2SRaphael Assenat xfer.rx_buf = chip->buf; 1248e12ecc2SRaphael Assenat chip->buf[0] = 0xbf; /* Burst read */ 1258e12ecc2SRaphael Assenat spi_message_add_tail(&xfer, &message); 1268e12ecc2SRaphael Assenat 1278e12ecc2SRaphael Assenat /* do the i/o */ 1288e12ecc2SRaphael Assenat status = spi_sync(spi, &message); 1298e12ecc2SRaphael Assenat if (status == 0) 1308e12ecc2SRaphael Assenat status = message.status; 1318e12ecc2SRaphael Assenat else 1328e12ecc2SRaphael Assenat return status; 1338e12ecc2SRaphael Assenat 1348e12ecc2SRaphael Assenat /* The chip sends data in this order: 1358e12ecc2SRaphael Assenat * Seconds, Minutes, Hours, Date, Month, Day, Year */ 1368e12ecc2SRaphael Assenat dt->tm_sec = BCD2BIN(chip->buf[1]); 1378e12ecc2SRaphael Assenat dt->tm_min = BCD2BIN(chip->buf[2]); 1388e12ecc2SRaphael Assenat dt->tm_hour = BCD2BIN(chip->buf[3]); 1398e12ecc2SRaphael Assenat dt->tm_mday = BCD2BIN(chip->buf[4]); 1408e12ecc2SRaphael Assenat dt->tm_mon = BCD2BIN(chip->buf[5] - 1); 1418e12ecc2SRaphael Assenat dt->tm_wday = BCD2BIN(chip->buf[6]); 1428e12ecc2SRaphael Assenat dt->tm_year = BCD2BIN(chip->buf[7]); 1438e12ecc2SRaphael Assenat 1448e12ecc2SRaphael Assenat century = BCD2BIN(tmp) * 100; 1458e12ecc2SRaphael Assenat 1468e12ecc2SRaphael Assenat dt->tm_year += century; 1478e12ecc2SRaphael Assenat dt->tm_year -= 1900; 1488e12ecc2SRaphael Assenat 1498e12ecc2SRaphael Assenat #ifdef MAX6902_DEBUG 1508e12ecc2SRaphael Assenat printk("\n%s : Read RTC values\n",__FUNCTION__); 1518e12ecc2SRaphael Assenat printk("tm_hour: %i\n",dt->tm_hour); 1528e12ecc2SRaphael Assenat printk("tm_min : %i\n",dt->tm_min); 1538e12ecc2SRaphael Assenat printk("tm_sec : %i\n",dt->tm_sec); 1548e12ecc2SRaphael Assenat printk("tm_year: %i\n",dt->tm_year); 1558e12ecc2SRaphael Assenat printk("tm_mon : %i\n",dt->tm_mon); 1568e12ecc2SRaphael Assenat printk("tm_mday: %i\n",dt->tm_mday); 1578e12ecc2SRaphael Assenat printk("tm_wday: %i\n",dt->tm_wday); 1588e12ecc2SRaphael Assenat #endif 1598e12ecc2SRaphael Assenat 1608e12ecc2SRaphael Assenat return 0; 1618e12ecc2SRaphael Assenat } 1628e12ecc2SRaphael Assenat 1638e12ecc2SRaphael Assenat static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) 1648e12ecc2SRaphael Assenat { 1658e12ecc2SRaphael Assenat dt->tm_year = dt->tm_year+1900; 1668e12ecc2SRaphael Assenat 1678e12ecc2SRaphael Assenat #ifdef MAX6902_DEBUG 1688e12ecc2SRaphael Assenat printk("\n%s : Setting RTC values\n",__FUNCTION__); 1698e12ecc2SRaphael Assenat printk("tm_sec : %i\n",dt->tm_sec); 1708e12ecc2SRaphael Assenat printk("tm_min : %i\n",dt->tm_min); 1718e12ecc2SRaphael Assenat printk("tm_hour: %i\n",dt->tm_hour); 1728e12ecc2SRaphael Assenat printk("tm_mday: %i\n",dt->tm_mday); 1738e12ecc2SRaphael Assenat printk("tm_wday: %i\n",dt->tm_wday); 1748e12ecc2SRaphael Assenat printk("tm_year: %i\n",dt->tm_year); 1758e12ecc2SRaphael Assenat #endif 1768e12ecc2SRaphael Assenat 1778e12ecc2SRaphael Assenat /* Remove write protection */ 1788e12ecc2SRaphael Assenat max6902_set_reg(dev, 0xF, 0); 1798e12ecc2SRaphael Assenat 1808e12ecc2SRaphael Assenat max6902_set_reg(dev, 0x01, BIN2BCD(dt->tm_sec)); 1818e12ecc2SRaphael Assenat max6902_set_reg(dev, 0x03, BIN2BCD(dt->tm_min)); 1828e12ecc2SRaphael Assenat max6902_set_reg(dev, 0x05, BIN2BCD(dt->tm_hour)); 1838e12ecc2SRaphael Assenat 1848e12ecc2SRaphael Assenat max6902_set_reg(dev, 0x07, BIN2BCD(dt->tm_mday)); 1858e12ecc2SRaphael Assenat max6902_set_reg(dev, 0x09, BIN2BCD(dt->tm_mon+1)); 1868e12ecc2SRaphael Assenat max6902_set_reg(dev, 0x0B, BIN2BCD(dt->tm_wday)); 1878e12ecc2SRaphael Assenat max6902_set_reg(dev, 0x0D, BIN2BCD(dt->tm_year%100)); 1888e12ecc2SRaphael Assenat max6902_set_reg(dev, 0x13, BIN2BCD(dt->tm_year/100)); 1898e12ecc2SRaphael Assenat 1908e12ecc2SRaphael Assenat /* Compulab used a delay here. However, the datasheet 1918e12ecc2SRaphael Assenat * does not mention a delay being required anywhere... */ 1928e12ecc2SRaphael Assenat /* delay(2000); */ 1938e12ecc2SRaphael Assenat 1948e12ecc2SRaphael Assenat /* Write protect */ 1958e12ecc2SRaphael Assenat max6902_set_reg(dev, 0xF, 0x80); 1968e12ecc2SRaphael Assenat 1978e12ecc2SRaphael Assenat return 0; 1988e12ecc2SRaphael Assenat } 1998e12ecc2SRaphael Assenat 2008e12ecc2SRaphael Assenat static int max6902_read_time(struct device *dev, struct rtc_time *tm) 2018e12ecc2SRaphael Assenat { 2028e12ecc2SRaphael Assenat return max6902_get_datetime(dev, tm); 2038e12ecc2SRaphael Assenat } 2048e12ecc2SRaphael Assenat 2058e12ecc2SRaphael Assenat static int max6902_set_time(struct device *dev, struct rtc_time *tm) 2068e12ecc2SRaphael Assenat { 2078e12ecc2SRaphael Assenat return max6902_set_datetime(dev, tm); 2088e12ecc2SRaphael Assenat } 2098e12ecc2SRaphael Assenat 210*ff8371acSDavid Brownell static const struct rtc_class_ops max6902_rtc_ops = { 2118e12ecc2SRaphael Assenat .read_time = max6902_read_time, 2128e12ecc2SRaphael Assenat .set_time = max6902_set_time, 2138e12ecc2SRaphael Assenat }; 2148e12ecc2SRaphael Assenat 2158e12ecc2SRaphael Assenat static int __devinit max6902_probe(struct spi_device *spi) 2168e12ecc2SRaphael Assenat { 2178e12ecc2SRaphael Assenat struct rtc_device *rtc; 2188e12ecc2SRaphael Assenat unsigned char tmp; 2198e12ecc2SRaphael Assenat struct max6902 *chip; 2208e12ecc2SRaphael Assenat int res; 2218e12ecc2SRaphael Assenat 2228e12ecc2SRaphael Assenat rtc = rtc_device_register("max6902", 2238e12ecc2SRaphael Assenat &spi->dev, &max6902_rtc_ops, THIS_MODULE); 2248e12ecc2SRaphael Assenat if (IS_ERR(rtc)) 2258e12ecc2SRaphael Assenat return PTR_ERR(rtc); 2268e12ecc2SRaphael Assenat 2278e12ecc2SRaphael Assenat spi->mode = SPI_MODE_3; 2288e12ecc2SRaphael Assenat spi->bits_per_word = 8; 2298e12ecc2SRaphael Assenat spi_setup(spi); 2308e12ecc2SRaphael Assenat 2318e12ecc2SRaphael Assenat chip = kzalloc(sizeof *chip, GFP_KERNEL); 2328e12ecc2SRaphael Assenat if (!chip) { 2338e12ecc2SRaphael Assenat rtc_device_unregister(rtc); 2348e12ecc2SRaphael Assenat return -ENOMEM; 2358e12ecc2SRaphael Assenat } 2368e12ecc2SRaphael Assenat chip->rtc = rtc; 2378e12ecc2SRaphael Assenat dev_set_drvdata(&spi->dev, chip); 2388e12ecc2SRaphael Assenat 2398e12ecc2SRaphael Assenat res = max6902_get_reg(&spi->dev, MAX6902_REG_SECONDS, &tmp); 2408e12ecc2SRaphael Assenat if (res) { 2418e12ecc2SRaphael Assenat rtc_device_unregister(rtc); 2428e12ecc2SRaphael Assenat return res; 2438e12ecc2SRaphael Assenat } 2448e12ecc2SRaphael Assenat 2458e12ecc2SRaphael Assenat return 0; 2468e12ecc2SRaphael Assenat } 2478e12ecc2SRaphael Assenat 2488e12ecc2SRaphael Assenat static int __devexit max6902_remove(struct spi_device *spi) 2498e12ecc2SRaphael Assenat { 2508e12ecc2SRaphael Assenat struct max6902 *chip = platform_get_drvdata(spi); 2518e12ecc2SRaphael Assenat struct rtc_device *rtc = chip->rtc; 2528e12ecc2SRaphael Assenat 2538e12ecc2SRaphael Assenat if (rtc) 2548e12ecc2SRaphael Assenat rtc_device_unregister(rtc); 2558e12ecc2SRaphael Assenat 2568e12ecc2SRaphael Assenat kfree(chip); 2578e12ecc2SRaphael Assenat 2588e12ecc2SRaphael Assenat return 0; 2598e12ecc2SRaphael Assenat } 2608e12ecc2SRaphael Assenat 2618e12ecc2SRaphael Assenat static struct spi_driver max6902_driver = { 2628e12ecc2SRaphael Assenat .driver = { 2638e12ecc2SRaphael Assenat .name = "max6902", 2648e12ecc2SRaphael Assenat .bus = &spi_bus_type, 2658e12ecc2SRaphael Assenat .owner = THIS_MODULE, 2668e12ecc2SRaphael Assenat }, 2678e12ecc2SRaphael Assenat .probe = max6902_probe, 2688e12ecc2SRaphael Assenat .remove = __devexit_p(max6902_remove), 2698e12ecc2SRaphael Assenat }; 2708e12ecc2SRaphael Assenat 2718e12ecc2SRaphael Assenat static __init int max6902_init(void) 2728e12ecc2SRaphael Assenat { 2738e12ecc2SRaphael Assenat printk("max6902 spi driver\n"); 2748e12ecc2SRaphael Assenat return spi_register_driver(&max6902_driver); 2758e12ecc2SRaphael Assenat } 2768e12ecc2SRaphael Assenat module_init(max6902_init); 2778e12ecc2SRaphael Assenat 2788e12ecc2SRaphael Assenat static __exit void max6902_exit(void) 2798e12ecc2SRaphael Assenat { 2808e12ecc2SRaphael Assenat spi_unregister_driver(&max6902_driver); 2818e12ecc2SRaphael Assenat } 2828e12ecc2SRaphael Assenat module_exit(max6902_exit); 2838e12ecc2SRaphael Assenat 2848e12ecc2SRaphael Assenat MODULE_DESCRIPTION ("max6902 spi RTC driver"); 2858e12ecc2SRaphael Assenat MODULE_AUTHOR ("Raphael Assenat"); 2868e12ecc2SRaphael Assenat MODULE_LICENSE ("GPL"); 287