1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2012 Sven Schnelle <svens@stackframe.org> 3 4 #include <linux/platform_device.h> 5 #include <linux/module.h> 6 #include <linux/init.h> 7 #include <linux/rtc.h> 8 #include <linux/types.h> 9 #include <linux/bcd.h> 10 #include <linux/delay.h> 11 #include <linux/gpio/consumer.h> 12 #include <linux/slab.h> 13 14 #include <linux/io.h> 15 16 #define DS2404_STATUS_REG 0x200 17 #define DS2404_CONTROL_REG 0x201 18 #define DS2404_RTC_REG 0x202 19 20 #define DS2404_WRITE_SCRATCHPAD_CMD 0x0f 21 #define DS2404_READ_SCRATCHPAD_CMD 0xaa 22 #define DS2404_COPY_SCRATCHPAD_CMD 0x55 23 #define DS2404_READ_MEMORY_CMD 0xf0 24 25 #define DS2404_RST 0 26 #define DS2404_CLK 1 27 #define DS2404_DQ 2 28 29 struct ds2404 { 30 struct device *dev; 31 struct gpio_desc *rst_gpiod; 32 struct gpio_desc *clk_gpiod; 33 struct gpio_desc *dq_gpiod; 34 }; 35 36 static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev) 37 { 38 struct device *dev = &pdev->dev; 39 40 /* This will de-assert RESET, declare this GPIO as GPIOD_ACTIVE_LOW */ 41 chip->rst_gpiod = devm_gpiod_get(dev, "rst", GPIOD_OUT_LOW); 42 if (IS_ERR(chip->rst_gpiod)) 43 return PTR_ERR(chip->rst_gpiod); 44 45 chip->clk_gpiod = devm_gpiod_get(dev, "clk", GPIOD_OUT_HIGH); 46 if (IS_ERR(chip->clk_gpiod)) 47 return PTR_ERR(chip->clk_gpiod); 48 49 chip->dq_gpiod = devm_gpiod_get(dev, "dq", GPIOD_ASIS); 50 if (IS_ERR(chip->dq_gpiod)) 51 return PTR_ERR(chip->dq_gpiod); 52 53 return 0; 54 } 55 56 static void ds2404_reset(struct ds2404 *chip) 57 { 58 gpiod_set_value(chip->rst_gpiod, 1); 59 udelay(1000); 60 gpiod_set_value(chip->rst_gpiod, 0); 61 gpiod_set_value(chip->clk_gpiod, 0); 62 gpiod_direction_output(chip->dq_gpiod, 0); 63 udelay(10); 64 } 65 66 static void ds2404_write_byte(struct ds2404 *chip, u8 byte) 67 { 68 int i; 69 70 gpiod_direction_output(chip->dq_gpiod, 1); 71 for (i = 0; i < 8; i++) { 72 gpiod_set_value(chip->dq_gpiod, byte & (1 << i)); 73 udelay(10); 74 gpiod_set_value(chip->clk_gpiod, 1); 75 udelay(10); 76 gpiod_set_value(chip->clk_gpiod, 0); 77 udelay(10); 78 } 79 } 80 81 static u8 ds2404_read_byte(struct ds2404 *chip) 82 { 83 int i; 84 u8 ret = 0; 85 86 gpiod_direction_input(chip->dq_gpiod); 87 88 for (i = 0; i < 8; i++) { 89 gpiod_set_value(chip->clk_gpiod, 0); 90 udelay(10); 91 if (gpiod_get_value(chip->dq_gpiod)) 92 ret |= 1 << i; 93 gpiod_set_value(chip->clk_gpiod, 1); 94 udelay(10); 95 } 96 return ret; 97 } 98 99 static void ds2404_read_memory(struct ds2404 *chip, u16 offset, 100 int length, u8 *out) 101 { 102 ds2404_reset(chip); 103 ds2404_write_byte(chip, DS2404_READ_MEMORY_CMD); 104 ds2404_write_byte(chip, offset & 0xff); 105 ds2404_write_byte(chip, (offset >> 8) & 0xff); 106 while (length--) 107 *out++ = ds2404_read_byte(chip); 108 } 109 110 static void ds2404_write_memory(struct ds2404 *chip, u16 offset, 111 int length, u8 *out) 112 { 113 int i; 114 u8 ta01, ta02, es; 115 116 ds2404_reset(chip); 117 ds2404_write_byte(chip, DS2404_WRITE_SCRATCHPAD_CMD); 118 ds2404_write_byte(chip, offset & 0xff); 119 ds2404_write_byte(chip, (offset >> 8) & 0xff); 120 121 for (i = 0; i < length; i++) 122 ds2404_write_byte(chip, out[i]); 123 124 ds2404_reset(chip); 125 ds2404_write_byte(chip, DS2404_READ_SCRATCHPAD_CMD); 126 127 ta01 = ds2404_read_byte(chip); 128 ta02 = ds2404_read_byte(chip); 129 es = ds2404_read_byte(chip); 130 131 for (i = 0; i < length; i++) { 132 if (out[i] != ds2404_read_byte(chip)) { 133 dev_err(chip->dev, "read invalid data\n"); 134 return; 135 } 136 } 137 138 ds2404_reset(chip); 139 ds2404_write_byte(chip, DS2404_COPY_SCRATCHPAD_CMD); 140 ds2404_write_byte(chip, ta01); 141 ds2404_write_byte(chip, ta02); 142 ds2404_write_byte(chip, es); 143 144 while (gpiod_get_value(chip->dq_gpiod)) 145 ; 146 } 147 148 static void ds2404_enable_osc(struct ds2404 *chip) 149 { 150 u8 in[1] = { 0x10 }; /* enable oscillator */ 151 152 ds2404_write_memory(chip, 0x201, 1, in); 153 } 154 155 static int ds2404_read_time(struct device *dev, struct rtc_time *dt) 156 { 157 struct ds2404 *chip = dev_get_drvdata(dev); 158 unsigned long time = 0; 159 __le32 hw_time = 0; 160 161 ds2404_read_memory(chip, 0x203, 4, (u8 *)&hw_time); 162 time = le32_to_cpu(hw_time); 163 164 rtc_time64_to_tm(time, dt); 165 return 0; 166 } 167 168 static int ds2404_set_time(struct device *dev, struct rtc_time *dt) 169 { 170 struct ds2404 *chip = dev_get_drvdata(dev); 171 u32 time = cpu_to_le32(rtc_tm_to_time64(dt)); 172 ds2404_write_memory(chip, 0x203, 4, (u8 *)&time); 173 return 0; 174 } 175 176 static const struct rtc_class_ops ds2404_rtc_ops = { 177 .read_time = ds2404_read_time, 178 .set_time = ds2404_set_time, 179 }; 180 181 static int rtc_probe(struct platform_device *pdev) 182 { 183 struct ds2404 *chip; 184 struct rtc_device *rtc; 185 int retval = -EBUSY; 186 187 chip = devm_kzalloc(&pdev->dev, sizeof(struct ds2404), GFP_KERNEL); 188 if (!chip) 189 return -ENOMEM; 190 191 chip->dev = &pdev->dev; 192 193 rtc = devm_rtc_allocate_device(&pdev->dev); 194 if (IS_ERR(rtc)) 195 return PTR_ERR(rtc); 196 197 retval = ds2404_gpio_map(chip, pdev); 198 if (retval) 199 return retval; 200 201 platform_set_drvdata(pdev, chip); 202 203 rtc->ops = &ds2404_rtc_ops; 204 rtc->range_max = U32_MAX; 205 206 retval = devm_rtc_register_device(rtc); 207 if (retval) 208 return retval; 209 210 ds2404_enable_osc(chip); 211 return 0; 212 } 213 214 static struct platform_driver rtc_device_driver = { 215 .probe = rtc_probe, 216 .driver = { 217 .name = "ds2404", 218 }, 219 }; 220 module_platform_driver(rtc_device_driver); 221 222 MODULE_DESCRIPTION("DS2404 RTC"); 223 MODULE_AUTHOR("Sven Schnelle"); 224 MODULE_LICENSE("GPL"); 225 MODULE_ALIAS("platform:ds2404"); 226