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