0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/bcd.h>
0011 #include <linux/clk-provider.h>
0012 #include <linux/device.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/kernel.h>
0015 #include <linux/mfd/ac100.h>
0016 #include <linux/module.h>
0017 #include <linux/mutex.h>
0018 #include <linux/of.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/regmap.h>
0021 #include <linux/rtc.h>
0022 #include <linux/types.h>
0023
0024
0025 #define AC100_RTC_CTRL_24HOUR BIT(0)
0026
0027
0028 #define AC100_CLKOUT_PRE_DIV_SHIFT 5
0029 #define AC100_CLKOUT_PRE_DIV_WIDTH 3
0030 #define AC100_CLKOUT_MUX_SHIFT 4
0031 #define AC100_CLKOUT_MUX_WIDTH 1
0032 #define AC100_CLKOUT_DIV_SHIFT 1
0033 #define AC100_CLKOUT_DIV_WIDTH 3
0034 #define AC100_CLKOUT_EN BIT(0)
0035
0036
0037 #define AC100_RTC_SEC_MASK GENMASK(6, 0)
0038 #define AC100_RTC_MIN_MASK GENMASK(6, 0)
0039 #define AC100_RTC_HOU_MASK GENMASK(5, 0)
0040 #define AC100_RTC_WEE_MASK GENMASK(2, 0)
0041 #define AC100_RTC_DAY_MASK GENMASK(5, 0)
0042 #define AC100_RTC_MON_MASK GENMASK(4, 0)
0043 #define AC100_RTC_YEA_MASK GENMASK(7, 0)
0044 #define AC100_RTC_YEA_LEAP BIT(15)
0045 #define AC100_RTC_UPD_TRIGGER BIT(15)
0046
0047
0048 #define AC100_ALM_INT_ENABLE BIT(0)
0049
0050 #define AC100_ALM_SEC_MASK GENMASK(6, 0)
0051 #define AC100_ALM_MIN_MASK GENMASK(6, 0)
0052 #define AC100_ALM_HOU_MASK GENMASK(5, 0)
0053 #define AC100_ALM_WEE_MASK GENMASK(2, 0)
0054 #define AC100_ALM_DAY_MASK GENMASK(5, 0)
0055 #define AC100_ALM_MON_MASK GENMASK(4, 0)
0056 #define AC100_ALM_YEA_MASK GENMASK(7, 0)
0057 #define AC100_ALM_ENABLE_FLAG BIT(15)
0058 #define AC100_ALM_UPD_TRIGGER BIT(15)
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 #define AC100_YEAR_MIN 1970
0069 #define AC100_YEAR_MAX 2069
0070 #define AC100_YEAR_OFF (AC100_YEAR_MIN - 1900)
0071
0072 struct ac100_clkout {
0073 struct clk_hw hw;
0074 struct regmap *regmap;
0075 u8 offset;
0076 };
0077
0078 #define to_ac100_clkout(_hw) container_of(_hw, struct ac100_clkout, hw)
0079
0080 #define AC100_RTC_32K_NAME "ac100-rtc-32k"
0081 #define AC100_RTC_32K_RATE 32768
0082 #define AC100_CLKOUT_NUM 3
0083
0084 static const char * const ac100_clkout_names[AC100_CLKOUT_NUM] = {
0085 "ac100-cko1-rtc",
0086 "ac100-cko2-rtc",
0087 "ac100-cko3-rtc",
0088 };
0089
0090 struct ac100_rtc_dev {
0091 struct rtc_device *rtc;
0092 struct device *dev;
0093 struct regmap *regmap;
0094 int irq;
0095 unsigned long alarm;
0096
0097 struct clk_hw *rtc_32k_clk;
0098 struct ac100_clkout clks[AC100_CLKOUT_NUM];
0099 struct clk_hw_onecell_data *clk_data;
0100 };
0101
0102
0103
0104
0105
0106 static const struct clk_div_table ac100_clkout_prediv[] = {
0107 { .val = 0, .div = 1 },
0108 { .val = 1, .div = 2 },
0109 { .val = 2, .div = 4 },
0110 { .val = 3, .div = 8 },
0111 { .val = 4, .div = 16 },
0112 { .val = 5, .div = 32 },
0113 { .val = 6, .div = 64 },
0114 { .val = 7, .div = 122 },
0115 { },
0116 };
0117
0118
0119 static unsigned long ac100_clkout_recalc_rate(struct clk_hw *hw,
0120 unsigned long prate)
0121 {
0122 struct ac100_clkout *clk = to_ac100_clkout(hw);
0123 unsigned int reg, div;
0124
0125 regmap_read(clk->regmap, clk->offset, ®);
0126
0127
0128 if (prate != AC100_RTC_32K_RATE) {
0129 div = (reg >> AC100_CLKOUT_PRE_DIV_SHIFT) &
0130 ((1 << AC100_CLKOUT_PRE_DIV_WIDTH) - 1);
0131 prate = divider_recalc_rate(hw, prate, div,
0132 ac100_clkout_prediv, 0,
0133 AC100_CLKOUT_PRE_DIV_WIDTH);
0134 }
0135
0136 div = (reg >> AC100_CLKOUT_DIV_SHIFT) &
0137 (BIT(AC100_CLKOUT_DIV_WIDTH) - 1);
0138 return divider_recalc_rate(hw, prate, div, NULL,
0139 CLK_DIVIDER_POWER_OF_TWO,
0140 AC100_CLKOUT_DIV_WIDTH);
0141 }
0142
0143 static long ac100_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
0144 unsigned long prate)
0145 {
0146 unsigned long best_rate = 0, tmp_rate, tmp_prate;
0147 int i;
0148
0149 if (prate == AC100_RTC_32K_RATE)
0150 return divider_round_rate(hw, rate, &prate, NULL,
0151 AC100_CLKOUT_DIV_WIDTH,
0152 CLK_DIVIDER_POWER_OF_TWO);
0153
0154 for (i = 0; ac100_clkout_prediv[i].div; i++) {
0155 tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[i].val);
0156 tmp_rate = divider_round_rate(hw, rate, &tmp_prate, NULL,
0157 AC100_CLKOUT_DIV_WIDTH,
0158 CLK_DIVIDER_POWER_OF_TWO);
0159
0160 if (tmp_rate > rate)
0161 continue;
0162 if (rate - tmp_rate < best_rate - tmp_rate)
0163 best_rate = tmp_rate;
0164 }
0165
0166 return best_rate;
0167 }
0168
0169 static int ac100_clkout_determine_rate(struct clk_hw *hw,
0170 struct clk_rate_request *req)
0171 {
0172 struct clk_hw *best_parent;
0173 unsigned long best = 0;
0174 int i, num_parents = clk_hw_get_num_parents(hw);
0175
0176 for (i = 0; i < num_parents; i++) {
0177 struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
0178 unsigned long tmp, prate;
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 if (!parent)
0198 continue;
0199
0200 prate = clk_hw_get_rate(parent);
0201
0202 tmp = ac100_clkout_round_rate(hw, req->rate, prate);
0203
0204 if (tmp > req->rate)
0205 continue;
0206 if (req->rate - tmp < req->rate - best) {
0207 best = tmp;
0208 best_parent = parent;
0209 }
0210 }
0211
0212 if (!best)
0213 return -EINVAL;
0214
0215 req->best_parent_hw = best_parent;
0216 req->best_parent_rate = best;
0217 req->rate = best;
0218
0219 return 0;
0220 }
0221
0222 static int ac100_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
0223 unsigned long prate)
0224 {
0225 struct ac100_clkout *clk = to_ac100_clkout(hw);
0226 int div = 0, pre_div = 0;
0227
0228 do {
0229 div = divider_get_val(rate * ac100_clkout_prediv[pre_div].div,
0230 prate, NULL, AC100_CLKOUT_DIV_WIDTH,
0231 CLK_DIVIDER_POWER_OF_TWO);
0232 if (div >= 0)
0233 break;
0234 } while (prate != AC100_RTC_32K_RATE &&
0235 ac100_clkout_prediv[++pre_div].div);
0236
0237 if (div < 0)
0238 return div;
0239
0240 pre_div = ac100_clkout_prediv[pre_div].val;
0241
0242 regmap_update_bits(clk->regmap, clk->offset,
0243 ((1 << AC100_CLKOUT_DIV_WIDTH) - 1) << AC100_CLKOUT_DIV_SHIFT |
0244 ((1 << AC100_CLKOUT_PRE_DIV_WIDTH) - 1) << AC100_CLKOUT_PRE_DIV_SHIFT,
0245 (div - 1) << AC100_CLKOUT_DIV_SHIFT |
0246 (pre_div - 1) << AC100_CLKOUT_PRE_DIV_SHIFT);
0247
0248 return 0;
0249 }
0250
0251 static int ac100_clkout_prepare(struct clk_hw *hw)
0252 {
0253 struct ac100_clkout *clk = to_ac100_clkout(hw);
0254
0255 return regmap_update_bits(clk->regmap, clk->offset, AC100_CLKOUT_EN,
0256 AC100_CLKOUT_EN);
0257 }
0258
0259 static void ac100_clkout_unprepare(struct clk_hw *hw)
0260 {
0261 struct ac100_clkout *clk = to_ac100_clkout(hw);
0262
0263 regmap_update_bits(clk->regmap, clk->offset, AC100_CLKOUT_EN, 0);
0264 }
0265
0266 static int ac100_clkout_is_prepared(struct clk_hw *hw)
0267 {
0268 struct ac100_clkout *clk = to_ac100_clkout(hw);
0269 unsigned int reg;
0270
0271 regmap_read(clk->regmap, clk->offset, ®);
0272
0273 return reg & AC100_CLKOUT_EN;
0274 }
0275
0276 static u8 ac100_clkout_get_parent(struct clk_hw *hw)
0277 {
0278 struct ac100_clkout *clk = to_ac100_clkout(hw);
0279 unsigned int reg;
0280
0281 regmap_read(clk->regmap, clk->offset, ®);
0282
0283 return (reg >> AC100_CLKOUT_MUX_SHIFT) & 0x1;
0284 }
0285
0286 static int ac100_clkout_set_parent(struct clk_hw *hw, u8 index)
0287 {
0288 struct ac100_clkout *clk = to_ac100_clkout(hw);
0289
0290 return regmap_update_bits(clk->regmap, clk->offset,
0291 BIT(AC100_CLKOUT_MUX_SHIFT),
0292 index ? BIT(AC100_CLKOUT_MUX_SHIFT) : 0);
0293 }
0294
0295 static const struct clk_ops ac100_clkout_ops = {
0296 .prepare = ac100_clkout_prepare,
0297 .unprepare = ac100_clkout_unprepare,
0298 .is_prepared = ac100_clkout_is_prepared,
0299 .recalc_rate = ac100_clkout_recalc_rate,
0300 .determine_rate = ac100_clkout_determine_rate,
0301 .get_parent = ac100_clkout_get_parent,
0302 .set_parent = ac100_clkout_set_parent,
0303 .set_rate = ac100_clkout_set_rate,
0304 };
0305
0306 static int ac100_rtc_register_clks(struct ac100_rtc_dev *chip)
0307 {
0308 struct device_node *np = chip->dev->of_node;
0309 const char *parents[2] = {AC100_RTC_32K_NAME};
0310 int i, ret;
0311
0312 chip->clk_data = devm_kzalloc(chip->dev,
0313 struct_size(chip->clk_data, hws,
0314 AC100_CLKOUT_NUM),
0315 GFP_KERNEL);
0316 if (!chip->clk_data)
0317 return -ENOMEM;
0318
0319 chip->rtc_32k_clk = clk_hw_register_fixed_rate(chip->dev,
0320 AC100_RTC_32K_NAME,
0321 NULL, 0,
0322 AC100_RTC_32K_RATE);
0323 if (IS_ERR(chip->rtc_32k_clk)) {
0324 ret = PTR_ERR(chip->rtc_32k_clk);
0325 dev_err(chip->dev, "Failed to register RTC-32k clock: %d\n",
0326 ret);
0327 return ret;
0328 }
0329
0330 parents[1] = of_clk_get_parent_name(np, 0);
0331 if (!parents[1]) {
0332 dev_err(chip->dev, "Failed to get ADDA 4M clock\n");
0333 return -EINVAL;
0334 }
0335
0336 for (i = 0; i < AC100_CLKOUT_NUM; i++) {
0337 struct ac100_clkout *clk = &chip->clks[i];
0338 struct clk_init_data init = {
0339 .name = ac100_clkout_names[i],
0340 .ops = &ac100_clkout_ops,
0341 .parent_names = parents,
0342 .num_parents = ARRAY_SIZE(parents),
0343 .flags = 0,
0344 };
0345
0346 of_property_read_string_index(np, "clock-output-names",
0347 i, &init.name);
0348 clk->regmap = chip->regmap;
0349 clk->offset = AC100_CLKOUT_CTRL1 + i;
0350 clk->hw.init = &init;
0351
0352 ret = devm_clk_hw_register(chip->dev, &clk->hw);
0353 if (ret) {
0354 dev_err(chip->dev, "Failed to register clk '%s': %d\n",
0355 init.name, ret);
0356 goto err_unregister_rtc_32k;
0357 }
0358
0359 chip->clk_data->hws[i] = &clk->hw;
0360 }
0361
0362 chip->clk_data->num = i;
0363 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, chip->clk_data);
0364 if (ret)
0365 goto err_unregister_rtc_32k;
0366
0367 return 0;
0368
0369 err_unregister_rtc_32k:
0370 clk_unregister_fixed_rate(chip->rtc_32k_clk->clk);
0371
0372 return ret;
0373 }
0374
0375 static void ac100_rtc_unregister_clks(struct ac100_rtc_dev *chip)
0376 {
0377 of_clk_del_provider(chip->dev->of_node);
0378 clk_unregister_fixed_rate(chip->rtc_32k_clk->clk);
0379 }
0380
0381
0382
0383
0384 static int ac100_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm)
0385 {
0386 struct ac100_rtc_dev *chip = dev_get_drvdata(dev);
0387 struct regmap *regmap = chip->regmap;
0388 u16 reg[7];
0389 int ret;
0390
0391 ret = regmap_bulk_read(regmap, AC100_RTC_SEC, reg, 7);
0392 if (ret)
0393 return ret;
0394
0395 rtc_tm->tm_sec = bcd2bin(reg[0] & AC100_RTC_SEC_MASK);
0396 rtc_tm->tm_min = bcd2bin(reg[1] & AC100_RTC_MIN_MASK);
0397 rtc_tm->tm_hour = bcd2bin(reg[2] & AC100_RTC_HOU_MASK);
0398 rtc_tm->tm_wday = bcd2bin(reg[3] & AC100_RTC_WEE_MASK);
0399 rtc_tm->tm_mday = bcd2bin(reg[4] & AC100_RTC_DAY_MASK);
0400 rtc_tm->tm_mon = bcd2bin(reg[5] & AC100_RTC_MON_MASK) - 1;
0401 rtc_tm->tm_year = bcd2bin(reg[6] & AC100_RTC_YEA_MASK) +
0402 AC100_YEAR_OFF;
0403
0404 return 0;
0405 }
0406
0407 static int ac100_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
0408 {
0409 struct ac100_rtc_dev *chip = dev_get_drvdata(dev);
0410 struct regmap *regmap = chip->regmap;
0411 int year;
0412 u16 reg[8];
0413
0414
0415 year = rtc_tm->tm_year - AC100_YEAR_OFF;
0416 if (year < 0 || year > (AC100_YEAR_MAX - 1900)) {
0417 dev_err(dev, "rtc only supports year in range %d - %d\n",
0418 AC100_YEAR_MIN, AC100_YEAR_MAX);
0419 return -EINVAL;
0420 }
0421
0422
0423 reg[0] = bin2bcd(rtc_tm->tm_sec) & AC100_RTC_SEC_MASK;
0424 reg[1] = bin2bcd(rtc_tm->tm_min) & AC100_RTC_MIN_MASK;
0425 reg[2] = bin2bcd(rtc_tm->tm_hour) & AC100_RTC_HOU_MASK;
0426 reg[3] = bin2bcd(rtc_tm->tm_wday) & AC100_RTC_WEE_MASK;
0427 reg[4] = bin2bcd(rtc_tm->tm_mday) & AC100_RTC_DAY_MASK;
0428 reg[5] = bin2bcd(rtc_tm->tm_mon + 1) & AC100_RTC_MON_MASK;
0429 reg[6] = bin2bcd(year) & AC100_RTC_YEA_MASK;
0430
0431 reg[7] = AC100_RTC_UPD_TRIGGER;
0432
0433
0434 if (is_leap_year(year + AC100_YEAR_OFF + 1900))
0435 reg[6] |= AC100_RTC_YEA_LEAP;
0436
0437 return regmap_bulk_write(regmap, AC100_RTC_SEC, reg, 8);
0438 }
0439
0440 static int ac100_rtc_alarm_irq_enable(struct device *dev, unsigned int en)
0441 {
0442 struct ac100_rtc_dev *chip = dev_get_drvdata(dev);
0443 struct regmap *regmap = chip->regmap;
0444 unsigned int val;
0445
0446 val = en ? AC100_ALM_INT_ENABLE : 0;
0447
0448 return regmap_write(regmap, AC100_ALM_INT_ENA, val);
0449 }
0450
0451 static int ac100_rtc_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
0452 {
0453 struct ac100_rtc_dev *chip = dev_get_drvdata(dev);
0454 struct regmap *regmap = chip->regmap;
0455 struct rtc_time *alrm_tm = &alrm->time;
0456 u16 reg[7];
0457 unsigned int val;
0458 int ret;
0459
0460 ret = regmap_read(regmap, AC100_ALM_INT_ENA, &val);
0461 if (ret)
0462 return ret;
0463
0464 alrm->enabled = !!(val & AC100_ALM_INT_ENABLE);
0465
0466 ret = regmap_bulk_read(regmap, AC100_ALM_SEC, reg, 7);
0467 if (ret)
0468 return ret;
0469
0470 alrm_tm->tm_sec = bcd2bin(reg[0] & AC100_ALM_SEC_MASK);
0471 alrm_tm->tm_min = bcd2bin(reg[1] & AC100_ALM_MIN_MASK);
0472 alrm_tm->tm_hour = bcd2bin(reg[2] & AC100_ALM_HOU_MASK);
0473 alrm_tm->tm_wday = bcd2bin(reg[3] & AC100_ALM_WEE_MASK);
0474 alrm_tm->tm_mday = bcd2bin(reg[4] & AC100_ALM_DAY_MASK);
0475 alrm_tm->tm_mon = bcd2bin(reg[5] & AC100_ALM_MON_MASK) - 1;
0476 alrm_tm->tm_year = bcd2bin(reg[6] & AC100_ALM_YEA_MASK) +
0477 AC100_YEAR_OFF;
0478
0479 return 0;
0480 }
0481
0482 static int ac100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
0483 {
0484 struct ac100_rtc_dev *chip = dev_get_drvdata(dev);
0485 struct regmap *regmap = chip->regmap;
0486 struct rtc_time *alrm_tm = &alrm->time;
0487 u16 reg[8];
0488 int year;
0489 int ret;
0490
0491
0492 year = alrm_tm->tm_year - AC100_YEAR_OFF;
0493 if (year < 0 || year > (AC100_YEAR_MAX - 1900)) {
0494 dev_err(dev, "alarm only supports year in range %d - %d\n",
0495 AC100_YEAR_MIN, AC100_YEAR_MAX);
0496 return -EINVAL;
0497 }
0498
0499
0500 reg[0] = (bin2bcd(alrm_tm->tm_sec) & AC100_ALM_SEC_MASK) |
0501 AC100_ALM_ENABLE_FLAG;
0502 reg[1] = (bin2bcd(alrm_tm->tm_min) & AC100_ALM_MIN_MASK) |
0503 AC100_ALM_ENABLE_FLAG;
0504 reg[2] = (bin2bcd(alrm_tm->tm_hour) & AC100_ALM_HOU_MASK) |
0505 AC100_ALM_ENABLE_FLAG;
0506
0507 reg[3] = bin2bcd(alrm_tm->tm_wday) & AC100_ALM_WEE_MASK;
0508 reg[4] = (bin2bcd(alrm_tm->tm_mday) & AC100_ALM_DAY_MASK) |
0509 AC100_ALM_ENABLE_FLAG;
0510 reg[5] = (bin2bcd(alrm_tm->tm_mon + 1) & AC100_ALM_MON_MASK) |
0511 AC100_ALM_ENABLE_FLAG;
0512 reg[6] = (bin2bcd(year) & AC100_ALM_YEA_MASK) |
0513 AC100_ALM_ENABLE_FLAG;
0514
0515 reg[7] = AC100_ALM_UPD_TRIGGER;
0516
0517 ret = regmap_bulk_write(regmap, AC100_ALM_SEC, reg, 8);
0518 if (ret)
0519 return ret;
0520
0521 return ac100_rtc_alarm_irq_enable(dev, alrm->enabled);
0522 }
0523
0524 static irqreturn_t ac100_rtc_irq(int irq, void *data)
0525 {
0526 struct ac100_rtc_dev *chip = data;
0527 struct regmap *regmap = chip->regmap;
0528 unsigned int val = 0;
0529 int ret;
0530
0531 rtc_lock(chip->rtc);
0532
0533
0534 ret = regmap_read(regmap, AC100_ALM_INT_STA, &val);
0535 if (ret)
0536 goto out;
0537
0538 if (val & AC100_ALM_INT_ENABLE) {
0539
0540 rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
0541
0542
0543 ret = regmap_write(regmap, AC100_ALM_INT_STA, val);
0544 if (ret)
0545 goto out;
0546
0547
0548 ret = ac100_rtc_alarm_irq_enable(chip->dev, 0);
0549 if (ret)
0550 goto out;
0551 }
0552
0553 out:
0554 rtc_unlock(chip->rtc);
0555 return IRQ_HANDLED;
0556 }
0557
0558 static const struct rtc_class_ops ac100_rtc_ops = {
0559 .read_time = ac100_rtc_get_time,
0560 .set_time = ac100_rtc_set_time,
0561 .read_alarm = ac100_rtc_get_alarm,
0562 .set_alarm = ac100_rtc_set_alarm,
0563 .alarm_irq_enable = ac100_rtc_alarm_irq_enable,
0564 };
0565
0566 static int ac100_rtc_probe(struct platform_device *pdev)
0567 {
0568 struct ac100_dev *ac100 = dev_get_drvdata(pdev->dev.parent);
0569 struct ac100_rtc_dev *chip;
0570 int ret;
0571
0572 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
0573 if (!chip)
0574 return -ENOMEM;
0575
0576 platform_set_drvdata(pdev, chip);
0577 chip->dev = &pdev->dev;
0578 chip->regmap = ac100->regmap;
0579
0580 chip->irq = platform_get_irq(pdev, 0);
0581 if (chip->irq < 0)
0582 return chip->irq;
0583
0584 chip->rtc = devm_rtc_allocate_device(&pdev->dev);
0585 if (IS_ERR(chip->rtc))
0586 return PTR_ERR(chip->rtc);
0587
0588 chip->rtc->ops = &ac100_rtc_ops;
0589
0590 ret = devm_request_threaded_irq(&pdev->dev, chip->irq, NULL,
0591 ac100_rtc_irq,
0592 IRQF_SHARED | IRQF_ONESHOT,
0593 dev_name(&pdev->dev), chip);
0594 if (ret) {
0595 dev_err(&pdev->dev, "Could not request IRQ\n");
0596 return ret;
0597 }
0598
0599
0600 regmap_write_bits(chip->regmap, AC100_RTC_CTRL, AC100_RTC_CTRL_24HOUR,
0601 AC100_RTC_CTRL_24HOUR);
0602
0603
0604 regmap_write(chip->regmap, AC100_ALM_INT_ENA, 0);
0605
0606
0607 regmap_write(chip->regmap, AC100_ALM_INT_STA, AC100_ALM_INT_ENABLE);
0608
0609 ret = ac100_rtc_register_clks(chip);
0610 if (ret)
0611 return ret;
0612
0613 return devm_rtc_register_device(chip->rtc);
0614 }
0615
0616 static int ac100_rtc_remove(struct platform_device *pdev)
0617 {
0618 struct ac100_rtc_dev *chip = platform_get_drvdata(pdev);
0619
0620 ac100_rtc_unregister_clks(chip);
0621
0622 return 0;
0623 }
0624
0625 static const struct of_device_id ac100_rtc_match[] = {
0626 { .compatible = "x-powers,ac100-rtc" },
0627 { },
0628 };
0629 MODULE_DEVICE_TABLE(of, ac100_rtc_match);
0630
0631 static struct platform_driver ac100_rtc_driver = {
0632 .probe = ac100_rtc_probe,
0633 .remove = ac100_rtc_remove,
0634 .driver = {
0635 .name = "ac100-rtc",
0636 .of_match_table = of_match_ptr(ac100_rtc_match),
0637 },
0638 };
0639 module_platform_driver(ac100_rtc_driver);
0640
0641 MODULE_DESCRIPTION("X-Powers AC100 RTC driver");
0642 MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
0643 MODULE_LICENSE("GPL v2");