0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
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
0050 void __iomem *ioaddress;
0051 int leftshift;
0052
0053
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
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
0214 v3020_set_reg(chip, V3020_CMD_CLOCK2RAM, 0);
0215
0216
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
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
0267 v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0);
0268
0269
0270
0271
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
0302
0303 for (i = 0; i < 8; i++)
0304 chip->ops->read_bit(chip);
0305
0306
0307
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
0315
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");