0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include <linux/init.h>
0031 #include <linux/module.h>
0032 #include <linux/of.h>
0033 #include <linux/of_address.h>
0034 #include <linux/platform_device.h>
0035 #include <linux/regmap.h>
0036 #include <linux/rtc.h>
0037 #include <linux/time.h>
0038
0039
0040 #define EXICSR 0
0041 #define EXICR 12
0042 #define EXIDATA 16
0043
0044
0045 #define EXICSR_DEV 0x380
0046 #define EXICSR_DEV1 0x100
0047 #define EXICSR_CLK 0x070
0048 #define EXICSR_CLK_1MHZ 0x000
0049 #define EXICSR_CLK_2MHZ 0x010
0050 #define EXICSR_CLK_4MHZ 0x020
0051 #define EXICSR_CLK_8MHZ 0x030
0052 #define EXICSR_CLK_16MHZ 0x040
0053 #define EXICSR_CLK_32MHZ 0x050
0054 #define EXICSR_INT 0x008
0055 #define EXICSR_INTSET 0x008
0056
0057 #define EXICR_TSTART 0x001
0058 #define EXICR_TRSMODE 0x002
0059 #define EXICR_TRSMODE_IMM 0x000
0060 #define EXICR_TRSTYPE 0x00C
0061 #define EXICR_TRSTYPE_R 0x000
0062 #define EXICR_TRSTYPE_W 0x004
0063 #define EXICR_TLEN 0x030
0064 #define EXICR_TLEN32 0x030
0065
0066
0067 #define RTC_EXICSR (EXICSR_DEV1 | EXICSR_CLK_8MHZ | EXICSR_INTSET)
0068 #define RTC_EXICR_W (EXICR_TSTART | EXICR_TRSMODE_IMM | EXICR_TRSTYPE_W | EXICR_TLEN32)
0069 #define RTC_EXICR_R (EXICR_TSTART | EXICR_TRSMODE_IMM | EXICR_TRSTYPE_R | EXICR_TLEN32)
0070 #define RTC_EXIDATA_W 0x80000000
0071
0072
0073 #define RTC_COUNTER 0x200000
0074 #define RTC_SRAM 0x200001
0075 #define RTC_SRAM_BIAS 0x200004
0076 #define RTC_SNAPSHOT 0x204000
0077 #define RTC_ONTMR 0x210000
0078 #define RTC_OFFTMR 0x210001
0079 #define RTC_TEST0 0x210004
0080 #define RTC_TEST1 0x210005
0081 #define RTC_TEST2 0x210006
0082 #define RTC_TEST3 0x210007
0083 #define RTC_CONTROL0 0x21000c
0084 #define RTC_CONTROL1 0x21000d
0085
0086
0087 #define RTC_CONTROL0_UNSTABLE_POWER 0x00000800
0088 #define RTC_CONTROL0_LOW_BATTERY 0x00000200
0089
0090 struct priv {
0091 struct regmap *regmap;
0092 void __iomem *iob;
0093 u32 rtc_bias;
0094 };
0095
0096 static int exi_read(void *context, u32 reg, u32 *data)
0097 {
0098 struct priv *d = (struct priv *)context;
0099 void __iomem *iob = d->iob;
0100
0101
0102
0103
0104
0105
0106 iowrite32be(RTC_EXICSR, iob + EXICSR);
0107 iowrite32be(reg << 8, iob + EXIDATA);
0108 iowrite32be(RTC_EXICR_W, iob + EXICR);
0109 while (!(ioread32be(iob + EXICSR) & EXICSR_INTSET))
0110 cpu_relax();
0111
0112
0113 iowrite32be(RTC_EXICSR, iob + EXICSR);
0114 iowrite32be(RTC_EXICR_R, iob + EXICR);
0115 while (!(ioread32be(iob + EXICSR) & EXICSR_INTSET))
0116 cpu_relax();
0117 *data = ioread32be(iob + EXIDATA);
0118
0119
0120 iowrite32be(0, iob + EXICSR);
0121
0122 return 0;
0123 }
0124
0125 static int exi_write(void *context, u32 reg, u32 data)
0126 {
0127 struct priv *d = (struct priv *)context;
0128 void __iomem *iob = d->iob;
0129
0130
0131
0132
0133
0134
0135 iowrite32be(RTC_EXICSR, iob + EXICSR);
0136 iowrite32be(RTC_EXIDATA_W | (reg << 8), iob + EXIDATA);
0137 iowrite32be(RTC_EXICR_W, iob + EXICR);
0138 while (!(ioread32be(iob + EXICSR) & EXICSR_INTSET))
0139 cpu_relax();
0140
0141
0142 iowrite32be(RTC_EXICSR, iob + EXICSR);
0143 iowrite32be(data, iob + EXIDATA);
0144 iowrite32be(RTC_EXICR_W, iob + EXICR);
0145 while (!(ioread32be(iob + EXICSR) & EXICSR_INTSET))
0146 cpu_relax();
0147
0148
0149 iowrite32be(0, iob + EXICSR);
0150
0151 return 0;
0152 }
0153
0154 static const struct regmap_bus exi_bus = {
0155
0156 .fast_io = true,
0157 .reg_read = exi_read,
0158 .reg_write = exi_write,
0159 };
0160
0161 static int gamecube_rtc_read_time(struct device *dev, struct rtc_time *t)
0162 {
0163 struct priv *d = dev_get_drvdata(dev);
0164 int ret;
0165 u32 counter;
0166 time64_t timestamp;
0167
0168 ret = regmap_read(d->regmap, RTC_COUNTER, &counter);
0169 if (ret)
0170 return ret;
0171
0172
0173 timestamp = (time64_t)d->rtc_bias + counter;
0174 rtc_time64_to_tm(timestamp, t);
0175
0176 return 0;
0177 }
0178
0179 static int gamecube_rtc_set_time(struct device *dev, struct rtc_time *t)
0180 {
0181 struct priv *d = dev_get_drvdata(dev);
0182 time64_t timestamp;
0183
0184
0185 timestamp = rtc_tm_to_time64(t);
0186 return regmap_write(d->regmap, RTC_COUNTER, timestamp - d->rtc_bias);
0187 }
0188
0189 static int gamecube_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
0190 {
0191 struct priv *d = dev_get_drvdata(dev);
0192 int value;
0193 int control0;
0194 int ret;
0195
0196 switch (cmd) {
0197 case RTC_VL_READ:
0198 ret = regmap_read(d->regmap, RTC_CONTROL0, &control0);
0199 if (ret)
0200 return ret;
0201
0202 value = 0;
0203 if (control0 & RTC_CONTROL0_UNSTABLE_POWER)
0204 value |= RTC_VL_DATA_INVALID;
0205 if (control0 & RTC_CONTROL0_LOW_BATTERY)
0206 value |= RTC_VL_BACKUP_LOW;
0207 return put_user(value, (unsigned int __user *)arg);
0208
0209 default:
0210 return -ENOIOCTLCMD;
0211 }
0212 }
0213
0214 static const struct rtc_class_ops gamecube_rtc_ops = {
0215 .read_time = gamecube_rtc_read_time,
0216 .set_time = gamecube_rtc_set_time,
0217 .ioctl = gamecube_rtc_ioctl,
0218 };
0219
0220 static int gamecube_rtc_read_offset_from_sram(struct priv *d)
0221 {
0222 struct device_node *np;
0223 int ret;
0224 struct resource res;
0225 void __iomem *hw_srnprot;
0226 u32 old;
0227
0228 np = of_find_compatible_node(NULL, NULL, "nintendo,latte-srnprot");
0229 if (!np)
0230 np = of_find_compatible_node(NULL, NULL,
0231 "nintendo,hollywood-srnprot");
0232 if (!np) {
0233 pr_info("HW_SRNPROT not found, assuming a GameCube\n");
0234 return regmap_read(d->regmap, RTC_SRAM_BIAS, &d->rtc_bias);
0235 }
0236
0237 ret = of_address_to_resource(np, 0, &res);
0238 of_node_put(np);
0239 if (ret) {
0240 pr_err("no io memory range found\n");
0241 return -1;
0242 }
0243
0244 hw_srnprot = ioremap(res.start, resource_size(&res));
0245 old = ioread32be(hw_srnprot);
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255 if (old != 0x7bf)
0256 iowrite32be(0x7bf, hw_srnprot);
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267 ret = regmap_read(d->regmap, RTC_SRAM_BIAS, &d->rtc_bias);
0268 if (ret) {
0269 pr_err("failed to get the RTC bias\n");
0270 iounmap(hw_srnprot);
0271 return -1;
0272 }
0273
0274
0275 if (old != 0x7bf)
0276 iowrite32be(old, hw_srnprot);
0277 iounmap(hw_srnprot);
0278
0279 return 0;
0280 }
0281
0282 static const struct regmap_range rtc_rd_ranges[] = {
0283 regmap_reg_range(0x200000, 0x200010),
0284 regmap_reg_range(0x204000, 0x204000),
0285 regmap_reg_range(0x210000, 0x210001),
0286 regmap_reg_range(0x210004, 0x210007),
0287 regmap_reg_range(0x21000c, 0x21000d),
0288 };
0289
0290 static const struct regmap_access_table rtc_rd_regs = {
0291 .yes_ranges = rtc_rd_ranges,
0292 .n_yes_ranges = ARRAY_SIZE(rtc_rd_ranges),
0293 };
0294
0295 static const struct regmap_range rtc_wr_ranges[] = {
0296 regmap_reg_range(0x200000, 0x200010),
0297 regmap_reg_range(0x204000, 0x204000),
0298 regmap_reg_range(0x210000, 0x210001),
0299 regmap_reg_range(0x21000d, 0x21000d),
0300 };
0301
0302 static const struct regmap_access_table rtc_wr_regs = {
0303 .yes_ranges = rtc_wr_ranges,
0304 .n_yes_ranges = ARRAY_SIZE(rtc_wr_ranges),
0305 };
0306
0307 static const struct regmap_config gamecube_rtc_regmap_config = {
0308 .reg_bits = 24,
0309 .val_bits = 32,
0310 .rd_table = &rtc_rd_regs,
0311 .wr_table = &rtc_wr_regs,
0312 .max_register = 0x21000d,
0313 .name = "gamecube-rtc",
0314 };
0315
0316 static int gamecube_rtc_probe(struct platform_device *pdev)
0317 {
0318 struct device *dev = &pdev->dev;
0319 struct rtc_device *rtc;
0320 struct priv *d;
0321 int ret;
0322
0323 d = devm_kzalloc(dev, sizeof(struct priv), GFP_KERNEL);
0324 if (!d)
0325 return -ENOMEM;
0326
0327 d->iob = devm_platform_ioremap_resource(pdev, 0);
0328 if (IS_ERR(d->iob))
0329 return PTR_ERR(d->iob);
0330
0331 d->regmap = devm_regmap_init(dev, &exi_bus, d,
0332 &gamecube_rtc_regmap_config);
0333 if (IS_ERR(d->regmap))
0334 return PTR_ERR(d->regmap);
0335
0336 ret = gamecube_rtc_read_offset_from_sram(d);
0337 if (ret)
0338 return ret;
0339 dev_dbg(dev, "SRAM bias: 0x%x", d->rtc_bias);
0340
0341 dev_set_drvdata(dev, d);
0342
0343 rtc = devm_rtc_allocate_device(dev);
0344 if (IS_ERR(rtc))
0345 return PTR_ERR(rtc);
0346
0347
0348
0349
0350
0351 rtc->range_min = 0;
0352 rtc->range_max = U32_MAX;
0353 rtc->ops = &gamecube_rtc_ops;
0354
0355 devm_rtc_register_device(rtc);
0356
0357 return 0;
0358 }
0359
0360 static const struct of_device_id gamecube_rtc_of_match[] = {
0361 {.compatible = "nintendo,latte-exi" },
0362 {.compatible = "nintendo,hollywood-exi" },
0363 {.compatible = "nintendo,flipper-exi" },
0364 { }
0365 };
0366 MODULE_DEVICE_TABLE(of, gamecube_rtc_of_match);
0367
0368 static struct platform_driver gamecube_rtc_driver = {
0369 .probe = gamecube_rtc_probe,
0370 .driver = {
0371 .name = "rtc-gamecube",
0372 .of_match_table = gamecube_rtc_of_match,
0373 },
0374 };
0375 module_platform_driver(gamecube_rtc_driver);
0376
0377 MODULE_AUTHOR("Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>");
0378 MODULE_DESCRIPTION("Nintendo GameCube, Wii and Wii U RTC driver");
0379 MODULE_LICENSE("GPL");