1/* drivers/rtc/rtc-v3020.c 2 * 3 * Copyright (C) 2006 8D Technologies inc. 4 * Copyright (C) 2004 Compulab Ltd. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Driver for the V3020 RTC 11 * 12 * Changelog: 13 * 14 * 10-May-2006: Raphael Assenat <raph@8d.com> 15 * - Converted to platform driver 16 * - Use the generic rtc class 17 * 18 * ??-???-2004: Someone at Compulab 19 * - Initial driver creation. 20 * 21 */ 22#include <linux/platform_device.h> 23#include <linux/module.h> 24#include <linux/init.h> 25#include <linux/rtc.h> 26#include <linux/types.h> 27#include <linux/bcd.h> 28#include <linux/rtc-v3020.h> 29#include <linux/delay.h> 30#include <linux/gpio.h> 31#include <linux/slab.h> 32 33#include <linux/io.h> 34 35#undef DEBUG 36 37struct v3020; 38 39struct v3020_chip_ops { 40 int (*map_io)(struct v3020 *chip, struct platform_device *pdev, 41 struct v3020_platform_data *pdata); 42 void (*unmap_io)(struct v3020 *chip); 43 unsigned char (*read_bit)(struct v3020 *chip); 44 void (*write_bit)(struct v3020 *chip, unsigned char bit); 45}; 46 47#define V3020_CS 0 48#define V3020_WR 1 49#define V3020_RD 2 50#define V3020_IO 3 51 52struct v3020 { 53 /* MMIO access */ 54 void __iomem *ioaddress; 55 int leftshift; 56 57 /* GPIO access */ 58 struct gpio *gpio; 59 60 struct v3020_chip_ops *ops; 61 62 struct rtc_device *rtc; 63}; 64 65 66static int v3020_mmio_map(struct v3020 *chip, struct platform_device *pdev, 67 struct v3020_platform_data *pdata) 68{ 69 if (pdev->num_resources != 1) 70 return -EBUSY; 71 72 if (pdev->resource[0].flags != IORESOURCE_MEM) 73 return -EBUSY; 74 75 chip->leftshift = pdata->leftshift; 76 chip->ioaddress = ioremap(pdev->resource[0].start, 1); 77 if (chip->ioaddress == NULL) 78 return -EBUSY; 79 80 return 0; 81} 82 83static void v3020_mmio_unmap(struct v3020 *chip) 84{ 85 iounmap(chip->ioaddress); 86} 87 88static void v3020_mmio_write_bit(struct v3020 *chip, unsigned char bit) 89{ 90 writel(bit << chip->leftshift, chip->ioaddress); 91} 92 93static unsigned char v3020_mmio_read_bit(struct v3020 *chip) 94{ 95 return !!(readl(chip->ioaddress) & (1 << chip->leftshift)); 96} 97 98static struct v3020_chip_ops v3020_mmio_ops = { 99 .map_io = v3020_mmio_map, 100 .unmap_io = v3020_mmio_unmap, 101 .read_bit = v3020_mmio_read_bit, 102 .write_bit = v3020_mmio_write_bit, 103}; 104 105static struct gpio v3020_gpio[] = { 106 { 0, GPIOF_OUT_INIT_HIGH, "RTC CS"}, 107 { 0, GPIOF_OUT_INIT_HIGH, "RTC WR"}, 108 { 0, GPIOF_OUT_INIT_HIGH, "RTC RD"}, 109 { 0, GPIOF_OUT_INIT_HIGH, "RTC IO"}, 110}; 111 112static int v3020_gpio_map(struct v3020 *chip, struct platform_device *pdev, 113 struct v3020_platform_data *pdata) 114{ 115 int err; 116 117 v3020_gpio[V3020_CS].gpio = pdata->gpio_cs; 118 v3020_gpio[V3020_WR].gpio = pdata->gpio_wr; 119 v3020_gpio[V3020_RD].gpio = pdata->gpio_rd; 120 v3020_gpio[V3020_IO].gpio = pdata->gpio_io; 121 122 err = gpio_request_array(v3020_gpio, ARRAY_SIZE(v3020_gpio)); 123 124 if (!err) 125 chip->gpio = v3020_gpio; 126 127 return err; 128} 129 130static void v3020_gpio_unmap(struct v3020 *chip) 131{ 132 gpio_free_array(v3020_gpio, ARRAY_SIZE(v3020_gpio)); 133} 134 135static void v3020_gpio_write_bit(struct v3020 *chip, unsigned char bit) 136{ 137 gpio_direction_output(chip->gpio[V3020_IO].gpio, bit); 138 gpio_set_value(chip->gpio[V3020_CS].gpio, 0); 139 gpio_set_value(chip->gpio[V3020_WR].gpio, 0); 140 udelay(1); 141 gpio_set_value(chip->gpio[V3020_WR].gpio, 1); 142 gpio_set_value(chip->gpio[V3020_CS].gpio, 1); 143} 144 145static unsigned char v3020_gpio_read_bit(struct v3020 *chip) 146{ 147 int bit; 148 149 gpio_direction_input(chip->gpio[V3020_IO].gpio); 150 gpio_set_value(chip->gpio[V3020_CS].gpio, 0); 151 gpio_set_value(chip->gpio[V3020_RD].gpio, 0); 152 udelay(1); 153 bit = !!gpio_get_value(chip->gpio[V3020_IO].gpio); 154 udelay(1); 155 gpio_set_value(chip->gpio[V3020_RD].gpio, 1); 156 gpio_set_value(chip->gpio[V3020_CS].gpio, 1); 157 158 return bit; 159} 160 161static struct v3020_chip_ops v3020_gpio_ops = { 162 .map_io = v3020_gpio_map, 163 .unmap_io = v3020_gpio_unmap, 164 .read_bit = v3020_gpio_read_bit, 165 .write_bit = v3020_gpio_write_bit, 166}; 167 168static void v3020_set_reg(struct v3020 *chip, unsigned char address, 169 unsigned char data) 170{ 171 int i; 172 unsigned char tmp; 173 174 tmp = address; 175 for (i = 0; i < 4; i++) { 176 chip->ops->write_bit(chip, (tmp & 1)); 177 tmp >>= 1; 178 udelay(1); 179 } 180 181 /* Commands dont have data */ 182 if (!V3020_IS_COMMAND(address)) { 183 for (i = 0; i < 8; i++) { 184 chip->ops->write_bit(chip, (data & 1)); 185 data >>= 1; 186 udelay(1); 187 } 188 } 189} 190 191static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address) 192{ 193 unsigned int data = 0; 194 int i; 195 196 for (i = 0; i < 4; i++) { 197 chip->ops->write_bit(chip, (address & 1)); 198 address >>= 1; 199 udelay(1); 200 } 201 202 for (i = 0; i < 8; i++) { 203 data >>= 1; 204 if (chip->ops->read_bit(chip)) 205 data |= 0x80; 206 udelay(1); 207 } 208 209 return data; 210} 211 212static int v3020_read_time(struct device *dev, struct rtc_time *dt) 213{ 214 struct v3020 *chip = dev_get_drvdata(dev); 215 int tmp; 216 217 /* Copy the current time to ram... */ 218 v3020_set_reg(chip, V3020_CMD_CLOCK2RAM, 0); 219 220 /* ...and then read constant values. */ 221 tmp = v3020_get_reg(chip, V3020_SECONDS); 222 dt->tm_sec = bcd2bin(tmp); 223 tmp = v3020_get_reg(chip, V3020_MINUTES); 224 dt->tm_min = bcd2bin(tmp); 225 tmp = v3020_get_reg(chip, V3020_HOURS); 226 dt->tm_hour = bcd2bin(tmp); 227 tmp = v3020_get_reg(chip, V3020_MONTH_DAY); 228 dt->tm_mday = bcd2bin(tmp); 229 tmp = v3020_get_reg(chip, V3020_MONTH); 230 dt->tm_mon = bcd2bin(tmp) - 1; 231 tmp = v3020_get_reg(chip, V3020_WEEK_DAY); 232 dt->tm_wday = bcd2bin(tmp); 233 tmp = v3020_get_reg(chip, V3020_YEAR); 234 dt->tm_year = bcd2bin(tmp)+100; 235 236 dev_dbg(dev, "\n%s : Read RTC values\n", __func__); 237 dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); 238 dev_dbg(dev, "tm_min : %i\n", dt->tm_min); 239 dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); 240 dev_dbg(dev, "tm_year: %i\n", dt->tm_year); 241 dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon); 242 dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); 243 dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); 244 245 return 0; 246} 247 248 249static int v3020_set_time(struct device *dev, struct rtc_time *dt) 250{ 251 struct v3020 *chip = dev_get_drvdata(dev); 252 253 dev_dbg(dev, "\n%s : Setting RTC values\n", __func__); 254 dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); 255 dev_dbg(dev, "tm_min : %i\n", dt->tm_min); 256 dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); 257 dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); 258 dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); 259 dev_dbg(dev, "tm_year: %i\n", dt->tm_year); 260 261 /* Write all the values to ram... */ 262 v3020_set_reg(chip, V3020_SECONDS, bin2bcd(dt->tm_sec)); 263 v3020_set_reg(chip, V3020_MINUTES, bin2bcd(dt->tm_min)); 264 v3020_set_reg(chip, V3020_HOURS, bin2bcd(dt->tm_hour)); 265 v3020_set_reg(chip, V3020_MONTH_DAY, bin2bcd(dt->tm_mday)); 266 v3020_set_reg(chip, V3020_MONTH, bin2bcd(dt->tm_mon + 1)); 267 v3020_set_reg(chip, V3020_WEEK_DAY, bin2bcd(dt->tm_wday)); 268 v3020_set_reg(chip, V3020_YEAR, bin2bcd(dt->tm_year % 100)); 269 270 /* ...and set the clock. */ 271 v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0); 272 273 /* Compulab used this delay here. I dont know why, 274 * the datasheet does not specify a delay. */ 275 /*mdelay(5);*/ 276 277 return 0; 278} 279 280static const struct rtc_class_ops v3020_rtc_ops = { 281 .read_time = v3020_read_time, 282 .set_time = v3020_set_time, 283}; 284 285static int rtc_probe(struct platform_device *pdev) 286{ 287 struct v3020_platform_data *pdata = dev_get_platdata(&pdev->dev); 288 struct v3020 *chip; 289 int retval = -EBUSY; 290 int i; 291 int temp; 292 293 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); 294 if (!chip) 295 return -ENOMEM; 296 297 if (pdata->use_gpio) 298 chip->ops = &v3020_gpio_ops; 299 else 300 chip->ops = &v3020_mmio_ops; 301 302 retval = chip->ops->map_io(chip, pdev, pdata); 303 if (retval) 304 return retval; 305 306 /* Make sure the v3020 expects a communication cycle 307 * by reading 8 times */ 308 for (i = 0; i < 8; i++) 309 temp = chip->ops->read_bit(chip); 310 311 /* Test chip by doing a write/read sequence 312 * to the chip ram */ 313 v3020_set_reg(chip, V3020_SECONDS, 0x33); 314 if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) { 315 retval = -ENODEV; 316 goto err_io; 317 } 318 319 /* Make sure frequency measurement mode, test modes, and lock 320 * are all disabled */ 321 v3020_set_reg(chip, V3020_STATUS_0, 0x0); 322 323 if (pdata->use_gpio) 324 dev_info(&pdev->dev, "Chip available at GPIOs " 325 "%d, %d, %d, %d\n", 326 chip->gpio[V3020_CS].gpio, chip->gpio[V3020_WR].gpio, 327 chip->gpio[V3020_RD].gpio, chip->gpio[V3020_IO].gpio); 328 else 329 dev_info(&pdev->dev, "Chip available at " 330 "physical address 0x%llx," 331 "data connected to D%d\n", 332 (unsigned long long)pdev->resource[0].start, 333 chip->leftshift); 334 335 platform_set_drvdata(pdev, chip); 336 337 chip->rtc = devm_rtc_device_register(&pdev->dev, "v3020", 338 &v3020_rtc_ops, THIS_MODULE); 339 if (IS_ERR(chip->rtc)) { 340 retval = PTR_ERR(chip->rtc); 341 goto err_io; 342 } 343 344 return 0; 345 346err_io: 347 chip->ops->unmap_io(chip); 348 349 return retval; 350} 351 352static int rtc_remove(struct platform_device *dev) 353{ 354 struct v3020 *chip = platform_get_drvdata(dev); 355 356 chip->ops->unmap_io(chip); 357 358 return 0; 359} 360 361static struct platform_driver rtc_device_driver = { 362 .probe = rtc_probe, 363 .remove = rtc_remove, 364 .driver = { 365 .name = "v3020", 366 }, 367}; 368 369module_platform_driver(rtc_device_driver); 370 371MODULE_DESCRIPTION("V3020 RTC"); 372MODULE_AUTHOR("Raphael Assenat"); 373MODULE_LICENSE("GPL"); 374MODULE_ALIAS("platform:v3020"); 375