Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (C) 2012 Sven Schnelle <svens@stackframe.org>
0003 
0004 #include <linux/platform_device.h>
0005 #include <linux/module.h>
0006 #include <linux/init.h>
0007 #include <linux/rtc.h>
0008 #include <linux/types.h>
0009 #include <linux/bcd.h>
0010 #include <linux/platform_data/rtc-ds2404.h>
0011 #include <linux/delay.h>
0012 #include <linux/gpio.h>
0013 #include <linux/slab.h>
0014 
0015 #include <linux/io.h>
0016 
0017 #define DS2404_STATUS_REG 0x200
0018 #define DS2404_CONTROL_REG 0x201
0019 #define DS2404_RTC_REG 0x202
0020 
0021 #define DS2404_WRITE_SCRATCHPAD_CMD 0x0f
0022 #define DS2404_READ_SCRATCHPAD_CMD 0xaa
0023 #define DS2404_COPY_SCRATCHPAD_CMD 0x55
0024 #define DS2404_READ_MEMORY_CMD 0xf0
0025 
0026 #define DS2404_RST  0
0027 #define DS2404_CLK  1
0028 #define DS2404_DQ   2
0029 
0030 struct ds2404_gpio {
0031     const char *name;
0032     unsigned int gpio;
0033 };
0034 
0035 struct ds2404 {
0036     struct ds2404_gpio *gpio;
0037     struct rtc_device *rtc;
0038 };
0039 
0040 static struct ds2404_gpio ds2404_gpio[] = {
0041     { "RTC RST", 0 },
0042     { "RTC CLK", 0 },
0043     { "RTC DQ", 0 },
0044 };
0045 
0046 static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev,
0047               struct ds2404_platform_data *pdata)
0048 {
0049     int i, err;
0050 
0051     ds2404_gpio[DS2404_RST].gpio = pdata->gpio_rst;
0052     ds2404_gpio[DS2404_CLK].gpio = pdata->gpio_clk;
0053     ds2404_gpio[DS2404_DQ].gpio = pdata->gpio_dq;
0054 
0055     for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) {
0056         err = gpio_request(ds2404_gpio[i].gpio, ds2404_gpio[i].name);
0057         if (err) {
0058             dev_err(&pdev->dev, "error mapping gpio %s: %d\n",
0059                 ds2404_gpio[i].name, err);
0060             goto err_request;
0061         }
0062         if (i != DS2404_DQ)
0063             gpio_direction_output(ds2404_gpio[i].gpio, 1);
0064     }
0065 
0066     chip->gpio = ds2404_gpio;
0067     return 0;
0068 
0069 err_request:
0070     while (--i >= 0)
0071         gpio_free(ds2404_gpio[i].gpio);
0072     return err;
0073 }
0074 
0075 static void ds2404_gpio_unmap(void *data)
0076 {
0077     int i;
0078 
0079     for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++)
0080         gpio_free(ds2404_gpio[i].gpio);
0081 }
0082 
0083 static void ds2404_reset(struct device *dev)
0084 {
0085     gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 0);
0086     udelay(1000);
0087     gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 1);
0088     gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
0089     gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 0);
0090     udelay(10);
0091 }
0092 
0093 static void ds2404_write_byte(struct device *dev, u8 byte)
0094 {
0095     int i;
0096 
0097     gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 1);
0098     for (i = 0; i < 8; i++) {
0099         gpio_set_value(ds2404_gpio[DS2404_DQ].gpio, byte & (1 << i));
0100         udelay(10);
0101         gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1);
0102         udelay(10);
0103         gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
0104         udelay(10);
0105     }
0106 }
0107 
0108 static u8 ds2404_read_byte(struct device *dev)
0109 {
0110     int i;
0111     u8 ret = 0;
0112 
0113     gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio);
0114 
0115     for (i = 0; i < 8; i++) {
0116         gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
0117         udelay(10);
0118         if (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio))
0119             ret |= 1 << i;
0120         gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1);
0121         udelay(10);
0122     }
0123     return ret;
0124 }
0125 
0126 static void ds2404_read_memory(struct device *dev, u16 offset,
0127                    int length, u8 *out)
0128 {
0129     ds2404_reset(dev);
0130     ds2404_write_byte(dev, DS2404_READ_MEMORY_CMD);
0131     ds2404_write_byte(dev, offset & 0xff);
0132     ds2404_write_byte(dev, (offset >> 8) & 0xff);
0133     while (length--)
0134         *out++ = ds2404_read_byte(dev);
0135 }
0136 
0137 static void ds2404_write_memory(struct device *dev, u16 offset,
0138                 int length, u8 *out)
0139 {
0140     int i;
0141     u8 ta01, ta02, es;
0142 
0143     ds2404_reset(dev);
0144     ds2404_write_byte(dev, DS2404_WRITE_SCRATCHPAD_CMD);
0145     ds2404_write_byte(dev, offset & 0xff);
0146     ds2404_write_byte(dev, (offset >> 8) & 0xff);
0147 
0148     for (i = 0; i < length; i++)
0149         ds2404_write_byte(dev, out[i]);
0150 
0151     ds2404_reset(dev);
0152     ds2404_write_byte(dev, DS2404_READ_SCRATCHPAD_CMD);
0153 
0154     ta01 = ds2404_read_byte(dev);
0155     ta02 = ds2404_read_byte(dev);
0156     es = ds2404_read_byte(dev);
0157 
0158     for (i = 0; i < length; i++) {
0159         if (out[i] != ds2404_read_byte(dev)) {
0160             dev_err(dev, "read invalid data\n");
0161             return;
0162         }
0163     }
0164 
0165     ds2404_reset(dev);
0166     ds2404_write_byte(dev, DS2404_COPY_SCRATCHPAD_CMD);
0167     ds2404_write_byte(dev, ta01);
0168     ds2404_write_byte(dev, ta02);
0169     ds2404_write_byte(dev, es);
0170 
0171     gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio);
0172     while (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio))
0173         ;
0174 }
0175 
0176 static void ds2404_enable_osc(struct device *dev)
0177 {
0178     u8 in[1] = { 0x10 }; /* enable oscillator */
0179     ds2404_write_memory(dev, 0x201, 1, in);
0180 }
0181 
0182 static int ds2404_read_time(struct device *dev, struct rtc_time *dt)
0183 {
0184     unsigned long time = 0;
0185     __le32 hw_time = 0;
0186 
0187     ds2404_read_memory(dev, 0x203, 4, (u8 *)&hw_time);
0188     time = le32_to_cpu(hw_time);
0189 
0190     rtc_time64_to_tm(time, dt);
0191     return 0;
0192 }
0193 
0194 static int ds2404_set_time(struct device *dev, struct rtc_time *dt)
0195 {
0196     u32 time = cpu_to_le32(rtc_tm_to_time64(dt));
0197     ds2404_write_memory(dev, 0x203, 4, (u8 *)&time);
0198     return 0;
0199 }
0200 
0201 static const struct rtc_class_ops ds2404_rtc_ops = {
0202     .read_time  = ds2404_read_time,
0203     .set_time   = ds2404_set_time,
0204 };
0205 
0206 static int rtc_probe(struct platform_device *pdev)
0207 {
0208     struct ds2404_platform_data *pdata = dev_get_platdata(&pdev->dev);
0209     struct ds2404 *chip;
0210     int retval = -EBUSY;
0211 
0212     chip = devm_kzalloc(&pdev->dev, sizeof(struct ds2404), GFP_KERNEL);
0213     if (!chip)
0214         return -ENOMEM;
0215 
0216     chip->rtc = devm_rtc_allocate_device(&pdev->dev);
0217     if (IS_ERR(chip->rtc))
0218         return PTR_ERR(chip->rtc);
0219 
0220     retval = ds2404_gpio_map(chip, pdev, pdata);
0221     if (retval)
0222         return retval;
0223 
0224     retval = devm_add_action_or_reset(&pdev->dev, ds2404_gpio_unmap, chip);
0225     if (retval)
0226         return retval;
0227 
0228     dev_info(&pdev->dev, "using GPIOs RST:%d, CLK:%d, DQ:%d\n",
0229          chip->gpio[DS2404_RST].gpio, chip->gpio[DS2404_CLK].gpio,
0230          chip->gpio[DS2404_DQ].gpio);
0231 
0232     platform_set_drvdata(pdev, chip);
0233 
0234     chip->rtc->ops = &ds2404_rtc_ops;
0235     chip->rtc->range_max = U32_MAX;
0236 
0237     retval = devm_rtc_register_device(chip->rtc);
0238     if (retval)
0239         return retval;
0240 
0241     ds2404_enable_osc(&pdev->dev);
0242     return 0;
0243 }
0244 
0245 static struct platform_driver rtc_device_driver = {
0246     .probe  = rtc_probe,
0247     .driver = {
0248         .name   = "ds2404",
0249     },
0250 };
0251 module_platform_driver(rtc_device_driver);
0252 
0253 MODULE_DESCRIPTION("DS2404 RTC");
0254 MODULE_AUTHOR("Sven Schnelle");
0255 MODULE_LICENSE("GPL");
0256 MODULE_ALIAS("platform:ds2404");