Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* drivers/rtc/rtc-v3020.c
0003  *
0004  * Copyright (C) 2006 8D Technologies inc.
0005  * Copyright (C) 2004 Compulab Ltd.
0006  *
0007  * Driver for the V3020 RTC
0008  *
0009  * Changelog:
0010  *
0011  *  10-May-2006: Raphael Assenat <raph@8d.com>
0012  *              - Converted to platform driver
0013  *              - Use the generic rtc class
0014  *
0015  *  ??-???-2004: Someone at Compulab
0016  *          - Initial driver creation.
0017  */
0018 #include <linux/platform_device.h>
0019 #include <linux/module.h>
0020 #include <linux/init.h>
0021 #include <linux/rtc.h>
0022 #include <linux/types.h>
0023 #include <linux/bcd.h>
0024 #include <linux/platform_data/rtc-v3020.h>
0025 #include <linux/delay.h>
0026 #include <linux/gpio.h>
0027 #include <linux/slab.h>
0028 
0029 #include <linux/io.h>
0030 
0031 #undef DEBUG
0032 
0033 struct v3020;
0034 
0035 struct v3020_chip_ops {
0036     int (*map_io)(struct v3020 *chip, struct platform_device *pdev,
0037               struct v3020_platform_data *pdata);
0038     void (*unmap_io)(struct v3020 *chip);
0039     unsigned char (*read_bit)(struct v3020 *chip);
0040     void (*write_bit)(struct v3020 *chip, unsigned char bit);
0041 };
0042 
0043 #define V3020_CS    0
0044 #define V3020_WR    1
0045 #define V3020_RD    2
0046 #define V3020_IO    3
0047 
0048 struct v3020 {
0049     /* MMIO access */
0050     void __iomem *ioaddress;
0051     int leftshift;
0052 
0053     /* GPIO access */
0054     struct gpio *gpio;
0055 
0056     const struct v3020_chip_ops *ops;
0057 
0058     struct rtc_device *rtc;
0059 };
0060 
0061 
0062 static int v3020_mmio_map(struct v3020 *chip, struct platform_device *pdev,
0063               struct v3020_platform_data *pdata)
0064 {
0065     if (pdev->num_resources != 1)
0066         return -EBUSY;
0067 
0068     if (pdev->resource[0].flags != IORESOURCE_MEM)
0069         return -EBUSY;
0070 
0071     chip->leftshift = pdata->leftshift;
0072     chip->ioaddress = ioremap(pdev->resource[0].start, 1);
0073     if (chip->ioaddress == NULL)
0074         return -EBUSY;
0075 
0076     return 0;
0077 }
0078 
0079 static void v3020_mmio_unmap(struct v3020 *chip)
0080 {
0081     iounmap(chip->ioaddress);
0082 }
0083 
0084 static void v3020_mmio_write_bit(struct v3020 *chip, unsigned char bit)
0085 {
0086     writel(bit << chip->leftshift, chip->ioaddress);
0087 }
0088 
0089 static unsigned char v3020_mmio_read_bit(struct v3020 *chip)
0090 {
0091     return !!(readl(chip->ioaddress) & (1 << chip->leftshift));
0092 }
0093 
0094 static const struct v3020_chip_ops v3020_mmio_ops = {
0095     .map_io     = v3020_mmio_map,
0096     .unmap_io   = v3020_mmio_unmap,
0097     .read_bit   = v3020_mmio_read_bit,
0098     .write_bit  = v3020_mmio_write_bit,
0099 };
0100 
0101 static struct gpio v3020_gpio[] = {
0102     { 0, GPIOF_OUT_INIT_HIGH, "RTC CS"},
0103     { 0, GPIOF_OUT_INIT_HIGH, "RTC WR"},
0104     { 0, GPIOF_OUT_INIT_HIGH, "RTC RD"},
0105     { 0, GPIOF_OUT_INIT_HIGH, "RTC IO"},
0106 };
0107 
0108 static int v3020_gpio_map(struct v3020 *chip, struct platform_device *pdev,
0109               struct v3020_platform_data *pdata)
0110 {
0111     int err;
0112 
0113     v3020_gpio[V3020_CS].gpio = pdata->gpio_cs;
0114     v3020_gpio[V3020_WR].gpio = pdata->gpio_wr;
0115     v3020_gpio[V3020_RD].gpio = pdata->gpio_rd;
0116     v3020_gpio[V3020_IO].gpio = pdata->gpio_io;
0117 
0118     err = gpio_request_array(v3020_gpio, ARRAY_SIZE(v3020_gpio));
0119 
0120     if (!err)
0121         chip->gpio = v3020_gpio;
0122 
0123     return err;
0124 }
0125 
0126 static void v3020_gpio_unmap(struct v3020 *chip)
0127 {
0128     gpio_free_array(v3020_gpio, ARRAY_SIZE(v3020_gpio));
0129 }
0130 
0131 static void v3020_gpio_write_bit(struct v3020 *chip, unsigned char bit)
0132 {
0133     gpio_direction_output(chip->gpio[V3020_IO].gpio, bit);
0134     gpio_set_value(chip->gpio[V3020_CS].gpio, 0);
0135     gpio_set_value(chip->gpio[V3020_WR].gpio, 0);
0136     udelay(1);
0137     gpio_set_value(chip->gpio[V3020_WR].gpio, 1);
0138     gpio_set_value(chip->gpio[V3020_CS].gpio, 1);
0139 }
0140 
0141 static unsigned char v3020_gpio_read_bit(struct v3020 *chip)
0142 {
0143     int bit;
0144 
0145     gpio_direction_input(chip->gpio[V3020_IO].gpio);
0146     gpio_set_value(chip->gpio[V3020_CS].gpio, 0);
0147     gpio_set_value(chip->gpio[V3020_RD].gpio, 0);
0148     udelay(1);
0149     bit = !!gpio_get_value(chip->gpio[V3020_IO].gpio);
0150     udelay(1);
0151     gpio_set_value(chip->gpio[V3020_RD].gpio, 1);
0152     gpio_set_value(chip->gpio[V3020_CS].gpio, 1);
0153 
0154     return bit;
0155 }
0156 
0157 static const struct v3020_chip_ops v3020_gpio_ops = {
0158     .map_io     = v3020_gpio_map,
0159     .unmap_io   = v3020_gpio_unmap,
0160     .read_bit   = v3020_gpio_read_bit,
0161     .write_bit  = v3020_gpio_write_bit,
0162 };
0163 
0164 static void v3020_set_reg(struct v3020 *chip, unsigned char address,
0165             unsigned char data)
0166 {
0167     int i;
0168     unsigned char tmp;
0169 
0170     tmp = address;
0171     for (i = 0; i < 4; i++) {
0172         chip->ops->write_bit(chip, (tmp & 1));
0173         tmp >>= 1;
0174         udelay(1);
0175     }
0176 
0177     /* Commands dont have data */
0178     if (!V3020_IS_COMMAND(address)) {
0179         for (i = 0; i < 8; i++) {
0180             chip->ops->write_bit(chip, (data & 1));
0181             data >>= 1;
0182             udelay(1);
0183         }
0184     }
0185 }
0186 
0187 static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address)
0188 {
0189     unsigned int data = 0;
0190     int i;
0191 
0192     for (i = 0; i < 4; i++) {
0193         chip->ops->write_bit(chip, (address & 1));
0194         address >>= 1;
0195         udelay(1);
0196     }
0197 
0198     for (i = 0; i < 8; i++) {
0199         data >>= 1;
0200         if (chip->ops->read_bit(chip))
0201             data |= 0x80;
0202         udelay(1);
0203     }
0204 
0205     return data;
0206 }
0207 
0208 static int v3020_read_time(struct device *dev, struct rtc_time *dt)
0209 {
0210     struct v3020 *chip = dev_get_drvdata(dev);
0211     int tmp;
0212 
0213     /* Copy the current time to ram... */
0214     v3020_set_reg(chip, V3020_CMD_CLOCK2RAM, 0);
0215 
0216     /* ...and then read constant values. */
0217     tmp = v3020_get_reg(chip, V3020_SECONDS);
0218     dt->tm_sec  = bcd2bin(tmp);
0219     tmp = v3020_get_reg(chip, V3020_MINUTES);
0220     dt->tm_min  = bcd2bin(tmp);
0221     tmp = v3020_get_reg(chip, V3020_HOURS);
0222     dt->tm_hour = bcd2bin(tmp);
0223     tmp = v3020_get_reg(chip, V3020_MONTH_DAY);
0224     dt->tm_mday = bcd2bin(tmp);
0225     tmp = v3020_get_reg(chip, V3020_MONTH);
0226     dt->tm_mon    = bcd2bin(tmp) - 1;
0227     tmp = v3020_get_reg(chip, V3020_WEEK_DAY);
0228     dt->tm_wday = bcd2bin(tmp);
0229     tmp = v3020_get_reg(chip, V3020_YEAR);
0230     dt->tm_year = bcd2bin(tmp)+100;
0231 
0232     dev_dbg(dev, "\n%s : Read RTC values\n", __func__);
0233     dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
0234     dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
0235     dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
0236     dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
0237     dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
0238     dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
0239     dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
0240 
0241     return 0;
0242 }
0243 
0244 
0245 static int v3020_set_time(struct device *dev, struct rtc_time *dt)
0246 {
0247     struct v3020 *chip = dev_get_drvdata(dev);
0248 
0249     dev_dbg(dev, "\n%s : Setting RTC values\n", __func__);
0250     dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
0251     dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
0252     dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
0253     dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
0254     dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
0255     dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
0256 
0257     /* Write all the values to ram... */
0258     v3020_set_reg(chip, V3020_SECONDS,  bin2bcd(dt->tm_sec));
0259     v3020_set_reg(chip, V3020_MINUTES,  bin2bcd(dt->tm_min));
0260     v3020_set_reg(chip, V3020_HOURS,    bin2bcd(dt->tm_hour));
0261     v3020_set_reg(chip, V3020_MONTH_DAY,    bin2bcd(dt->tm_mday));
0262     v3020_set_reg(chip, V3020_MONTH,    bin2bcd(dt->tm_mon + 1));
0263     v3020_set_reg(chip, V3020_WEEK_DAY, bin2bcd(dt->tm_wday));
0264     v3020_set_reg(chip, V3020_YEAR,     bin2bcd(dt->tm_year % 100));
0265 
0266     /* ...and set the clock. */
0267     v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0);
0268 
0269     /* Compulab used this delay here. I dont know why,
0270      * the datasheet does not specify a delay. */
0271     /*mdelay(5);*/
0272 
0273     return 0;
0274 }
0275 
0276 static const struct rtc_class_ops v3020_rtc_ops = {
0277     .read_time  = v3020_read_time,
0278     .set_time   = v3020_set_time,
0279 };
0280 
0281 static int rtc_probe(struct platform_device *pdev)
0282 {
0283     struct v3020_platform_data *pdata = dev_get_platdata(&pdev->dev);
0284     struct v3020 *chip;
0285     int retval;
0286     int i;
0287 
0288     chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
0289     if (!chip)
0290         return -ENOMEM;
0291 
0292     if (pdata->use_gpio)
0293         chip->ops = &v3020_gpio_ops;
0294     else
0295         chip->ops = &v3020_mmio_ops;
0296 
0297     retval = chip->ops->map_io(chip, pdev, pdata);
0298     if (retval)
0299         return retval;
0300 
0301     /* Make sure the v3020 expects a communication cycle
0302      * by reading 8 times */
0303     for (i = 0; i < 8; i++)
0304         chip->ops->read_bit(chip);
0305 
0306     /* Test chip by doing a write/read sequence
0307      * to the chip ram */
0308     v3020_set_reg(chip, V3020_SECONDS, 0x33);
0309     if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
0310         retval = -ENODEV;
0311         goto err_io;
0312     }
0313 
0314     /* Make sure frequency measurement mode, test modes, and lock
0315      * are all disabled */
0316     v3020_set_reg(chip, V3020_STATUS_0, 0x0);
0317 
0318     if (pdata->use_gpio)
0319         dev_info(&pdev->dev, "Chip available at GPIOs "
0320              "%d, %d, %d, %d\n",
0321              chip->gpio[V3020_CS].gpio, chip->gpio[V3020_WR].gpio,
0322              chip->gpio[V3020_RD].gpio, chip->gpio[V3020_IO].gpio);
0323     else
0324         dev_info(&pdev->dev, "Chip available at "
0325              "physical address 0x%llx,"
0326              "data connected to D%d\n",
0327              (unsigned long long)pdev->resource[0].start,
0328              chip->leftshift);
0329 
0330     platform_set_drvdata(pdev, chip);
0331 
0332     chip->rtc = devm_rtc_device_register(&pdev->dev, "v3020",
0333                     &v3020_rtc_ops, THIS_MODULE);
0334     if (IS_ERR(chip->rtc)) {
0335         retval = PTR_ERR(chip->rtc);
0336         goto err_io;
0337     }
0338 
0339     return 0;
0340 
0341 err_io:
0342     chip->ops->unmap_io(chip);
0343 
0344     return retval;
0345 }
0346 
0347 static int rtc_remove(struct platform_device *dev)
0348 {
0349     struct v3020 *chip = platform_get_drvdata(dev);
0350 
0351     chip->ops->unmap_io(chip);
0352 
0353     return 0;
0354 }
0355 
0356 static struct platform_driver rtc_device_driver = {
0357     .probe  = rtc_probe,
0358     .remove = rtc_remove,
0359     .driver = {
0360         .name   = "v3020",
0361     },
0362 };
0363 
0364 module_platform_driver(rtc_device_driver);
0365 
0366 MODULE_DESCRIPTION("V3020 RTC");
0367 MODULE_AUTHOR("Raphael Assenat");
0368 MODULE_LICENSE("GPL");
0369 MODULE_ALIAS("platform:v3020");