This source file includes following definitions.
- rx6110_rtc_tm_to_data
- rx6110_data_to_rtc_tm
- rx6110_set_time
- rx6110_get_time
- rx6110_init
- rx6110_probe
- rx6110_remove
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 #include <linux/bcd.h>
  18 #include <linux/init.h>
  19 #include <linux/kernel.h>
  20 #include <linux/module.h>
  21 #include <linux/of_gpio.h>
  22 #include <linux/regmap.h>
  23 #include <linux/rtc.h>
  24 #include <linux/of.h>
  25 #include <linux/of_device.h>
  26 #include <linux/spi/spi.h>
  27 
  28 
  29 #define RX6110_REG_SEC          0x10
  30 #define RX6110_REG_MIN          0x11
  31 #define RX6110_REG_HOUR         0x12
  32 #define RX6110_REG_WDAY         0x13
  33 #define RX6110_REG_MDAY         0x14
  34 #define RX6110_REG_MONTH        0x15
  35 #define RX6110_REG_YEAR         0x16
  36 #define RX6110_REG_RES1         0x17
  37 #define RX6110_REG_ALMIN        0x18
  38 #define RX6110_REG_ALHOUR       0x19
  39 #define RX6110_REG_ALWDAY       0x1A
  40 #define RX6110_REG_TCOUNT0      0x1B
  41 #define RX6110_REG_TCOUNT1      0x1C
  42 #define RX6110_REG_EXT          0x1D
  43 #define RX6110_REG_FLAG         0x1E
  44 #define RX6110_REG_CTRL         0x1F
  45 #define RX6110_REG_USER0        0x20
  46 #define RX6110_REG_USER1        0x21
  47 #define RX6110_REG_USER2        0x22
  48 #define RX6110_REG_USER3        0x23
  49 #define RX6110_REG_USER4        0x24
  50 #define RX6110_REG_USER5        0x25
  51 #define RX6110_REG_USER6        0x26
  52 #define RX6110_REG_USER7        0x27
  53 #define RX6110_REG_USER8        0x28
  54 #define RX6110_REG_USER9        0x29
  55 #define RX6110_REG_USERA        0x2A
  56 #define RX6110_REG_USERB        0x2B
  57 #define RX6110_REG_USERC        0x2C
  58 #define RX6110_REG_USERD        0x2D
  59 #define RX6110_REG_USERE        0x2E
  60 #define RX6110_REG_USERF        0x2F
  61 #define RX6110_REG_RES2         0x30
  62 #define RX6110_REG_RES3         0x31
  63 #define RX6110_REG_IRQ          0x32
  64 
  65 #define RX6110_BIT_ALARM_EN             BIT(7)
  66 
  67 
  68 #define RX6110_BIT_EXT_TSEL0            BIT(0)
  69 #define RX6110_BIT_EXT_TSEL1            BIT(1)
  70 #define RX6110_BIT_EXT_TSEL2            BIT(2)
  71 #define RX6110_BIT_EXT_WADA             BIT(3)
  72 #define RX6110_BIT_EXT_TE               BIT(4)
  73 #define RX6110_BIT_EXT_USEL             BIT(5)
  74 #define RX6110_BIT_EXT_FSEL0            BIT(6)
  75 #define RX6110_BIT_EXT_FSEL1            BIT(7)
  76 
  77 
  78 #define RX6110_BIT_FLAG_VLF             BIT(1)
  79 #define RX6110_BIT_FLAG_AF              BIT(3)
  80 #define RX6110_BIT_FLAG_TF              BIT(4)
  81 #define RX6110_BIT_FLAG_UF              BIT(5)
  82 
  83 
  84 #define RX6110_BIT_CTRL_TBKE            BIT(0)
  85 #define RX6110_BIT_CTRL_TBKON           BIT(1)
  86 #define RX6110_BIT_CTRL_TSTP            BIT(2)
  87 #define RX6110_BIT_CTRL_AIE             BIT(3)
  88 #define RX6110_BIT_CTRL_TIE             BIT(4)
  89 #define RX6110_BIT_CTRL_UIE             BIT(5)
  90 #define RX6110_BIT_CTRL_STOP            BIT(6)
  91 #define RX6110_BIT_CTRL_TEST            BIT(7)
  92 
  93 enum {
  94         RTC_SEC = 0,
  95         RTC_MIN,
  96         RTC_HOUR,
  97         RTC_WDAY,
  98         RTC_MDAY,
  99         RTC_MONTH,
 100         RTC_YEAR,
 101         RTC_NR_TIME
 102 };
 103 
 104 #define RX6110_DRIVER_NAME              "rx6110"
 105 
 106 struct rx6110_data {
 107         struct rtc_device *rtc;
 108         struct regmap *regmap;
 109 };
 110 
 111 
 112 
 113 
 114 
 115 
 116 
 117 static int rx6110_rtc_tm_to_data(struct rtc_time *tm, u8 *data)
 118 {
 119         pr_debug("%s: date %ptRr\n", __func__, tm);
 120 
 121         
 122 
 123 
 124 
 125 
 126         if (tm->tm_year < 100 || tm->tm_year >= 200)
 127                 return -EINVAL;
 128 
 129         data[RTC_SEC] = bin2bcd(tm->tm_sec);
 130         data[RTC_MIN] = bin2bcd(tm->tm_min);
 131         data[RTC_HOUR] = bin2bcd(tm->tm_hour);
 132         data[RTC_WDAY] = BIT(bin2bcd(tm->tm_wday));
 133         data[RTC_MDAY] = bin2bcd(tm->tm_mday);
 134         data[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);
 135         data[RTC_YEAR] = bin2bcd(tm->tm_year % 100);
 136 
 137         return 0;
 138 }
 139 
 140 
 141 
 142 
 143 
 144 
 145 
 146 static int rx6110_data_to_rtc_tm(u8 *data, struct rtc_time *tm)
 147 {
 148         tm->tm_sec = bcd2bin(data[RTC_SEC] & 0x7f);
 149         tm->tm_min = bcd2bin(data[RTC_MIN] & 0x7f);
 150         
 151         tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);
 152         tm->tm_wday = ffs(data[RTC_WDAY] & 0x7f);
 153         tm->tm_mday = bcd2bin(data[RTC_MDAY] & 0x3f);
 154         tm->tm_mon = bcd2bin(data[RTC_MONTH] & 0x1f) - 1;
 155         tm->tm_year = bcd2bin(data[RTC_YEAR]) + 100;
 156 
 157         pr_debug("%s: date %ptRr\n", __func__, tm);
 158 
 159         
 160 
 161 
 162 
 163 
 164         if (tm->tm_year < 100 || tm->tm_year >= 200)
 165                 return -EINVAL;
 166 
 167         return 0;
 168 }
 169 
 170 
 171 
 172 
 173 
 174 
 175 
 176 
 177 
 178 
 179 
 180 
 181 
 182 
 183 static int rx6110_set_time(struct device *dev, struct rtc_time *tm)
 184 {
 185         struct rx6110_data *rx6110 = dev_get_drvdata(dev);
 186         u8 data[RTC_NR_TIME];
 187         int ret;
 188 
 189         ret = rx6110_rtc_tm_to_data(tm, data);
 190         if (ret < 0)
 191                 return ret;
 192 
 193         
 194         ret = regmap_update_bits(rx6110->regmap, RX6110_REG_CTRL,
 195                                  RX6110_BIT_CTRL_STOP, RX6110_BIT_CTRL_STOP);
 196         if (ret)
 197                 return ret;
 198 
 199         ret = regmap_bulk_write(rx6110->regmap, RX6110_REG_SEC, data,
 200                                 RTC_NR_TIME);
 201         if (ret)
 202                 return ret;
 203 
 204         
 205         ret = regmap_update_bits(rx6110->regmap, RX6110_REG_FLAG,
 206                                  RX6110_BIT_FLAG_VLF, 0);
 207         if (ret)
 208                 return ret;
 209 
 210         
 211         ret = regmap_update_bits(rx6110->regmap, RX6110_REG_CTRL,
 212                                  RX6110_BIT_CTRL_STOP, 0);
 213 
 214         return ret;
 215 }
 216 
 217 
 218 
 219 
 220 
 221 
 222 static int rx6110_get_time(struct device *dev, struct rtc_time *tm)
 223 {
 224         struct rx6110_data *rx6110 = dev_get_drvdata(dev);
 225         u8 data[RTC_NR_TIME];
 226         int flags;
 227         int ret;
 228 
 229         ret = regmap_read(rx6110->regmap, RX6110_REG_FLAG, &flags);
 230         if (ret)
 231                 return -EINVAL;
 232 
 233         
 234         if ((flags & RX6110_BIT_FLAG_VLF)) {
 235                 dev_warn(dev, "Voltage low, data is invalid.\n");
 236                 return -EINVAL;
 237         }
 238 
 239         
 240         ret = regmap_bulk_read(rx6110->regmap, RX6110_REG_SEC, data,
 241                                RTC_NR_TIME);
 242         if (ret)
 243                 return ret;
 244 
 245         ret = rx6110_data_to_rtc_tm(data, tm);
 246         if (ret)
 247                 return ret;
 248 
 249         dev_dbg(dev, "%s: date %ptRr\n", __func__, tm);
 250 
 251         return 0;
 252 }
 253 
 254 static const struct reg_sequence rx6110_default_regs[] = {
 255         { RX6110_REG_RES1,   0xB8 },
 256         { RX6110_REG_RES2,   0x00 },
 257         { RX6110_REG_RES3,   0x10 },
 258         { RX6110_REG_IRQ,    0x00 },
 259         { RX6110_REG_ALMIN,  0x00 },
 260         { RX6110_REG_ALHOUR, 0x00 },
 261         { RX6110_REG_ALWDAY, 0x00 },
 262 };
 263 
 264 
 265 
 266 
 267 
 268 
 269 
 270 static int rx6110_init(struct rx6110_data *rx6110)
 271 {
 272         struct rtc_device *rtc = rx6110->rtc;
 273         int flags;
 274         int ret;
 275 
 276         ret = regmap_update_bits(rx6110->regmap, RX6110_REG_EXT,
 277                                  RX6110_BIT_EXT_TE, 0);
 278         if (ret)
 279                 return ret;
 280 
 281         ret = regmap_register_patch(rx6110->regmap, rx6110_default_regs,
 282                                     ARRAY_SIZE(rx6110_default_regs));
 283         if (ret)
 284                 return ret;
 285 
 286         ret = regmap_read(rx6110->regmap, RX6110_REG_FLAG, &flags);
 287         if (ret)
 288                 return ret;
 289 
 290         
 291         if ((flags & RX6110_BIT_FLAG_VLF))
 292                 dev_warn(&rtc->dev, "Voltage low, data loss detected.\n");
 293 
 294         
 295         if (flags & RX6110_BIT_FLAG_AF)
 296                 dev_warn(&rtc->dev, "An alarm may have been missed.\n");
 297 
 298         
 299         if (flags & RX6110_BIT_FLAG_TF)
 300                 dev_warn(&rtc->dev, "Periodic timer was detected\n");
 301 
 302         
 303         if (flags & RX6110_BIT_FLAG_UF)
 304                 dev_warn(&rtc->dev, "Update timer was detected\n");
 305 
 306         
 307         ret = regmap_update_bits(rx6110->regmap, RX6110_REG_FLAG,
 308                                  RX6110_BIT_FLAG_AF |
 309                                  RX6110_BIT_FLAG_UF |
 310                                  RX6110_BIT_FLAG_TF,
 311                                  0);
 312 
 313         return ret;
 314 }
 315 
 316 static const struct rtc_class_ops rx6110_rtc_ops = {
 317         .read_time = rx6110_get_time,
 318         .set_time = rx6110_set_time,
 319 };
 320 
 321 static struct regmap_config regmap_spi_config = {
 322         .reg_bits = 8,
 323         .val_bits = 8,
 324         .max_register = RX6110_REG_IRQ,
 325         .read_flag_mask = 0x80,
 326 };
 327 
 328 
 329 
 330 
 331 
 332 static int rx6110_probe(struct spi_device *spi)
 333 {
 334         struct rx6110_data *rx6110;
 335         int err;
 336 
 337         if ((spi->bits_per_word && spi->bits_per_word != 8) ||
 338             (spi->max_speed_hz > 2000000) ||
 339             (spi->mode != (SPI_CS_HIGH | SPI_CPOL | SPI_CPHA))) {
 340                 dev_warn(&spi->dev, "SPI settings: bits_per_word: %d, max_speed_hz: %d, mode: %xh\n",
 341                          spi->bits_per_word, spi->max_speed_hz, spi->mode);
 342                 dev_warn(&spi->dev, "driving device in an unsupported mode");
 343         }
 344 
 345         rx6110 = devm_kzalloc(&spi->dev, sizeof(*rx6110), GFP_KERNEL);
 346         if (!rx6110)
 347                 return -ENOMEM;
 348 
 349         rx6110->regmap = devm_regmap_init_spi(spi, ®map_spi_config);
 350         if (IS_ERR(rx6110->regmap)) {
 351                 dev_err(&spi->dev, "regmap init failed for rtc rx6110\n");
 352                 return PTR_ERR(rx6110->regmap);
 353         }
 354 
 355         spi_set_drvdata(spi, rx6110);
 356 
 357         rx6110->rtc = devm_rtc_device_register(&spi->dev,
 358                                                RX6110_DRIVER_NAME,
 359                                                &rx6110_rtc_ops, THIS_MODULE);
 360 
 361         if (IS_ERR(rx6110->rtc))
 362                 return PTR_ERR(rx6110->rtc);
 363 
 364         err = rx6110_init(rx6110);
 365         if (err)
 366                 return err;
 367 
 368         rx6110->rtc->max_user_freq = 1;
 369 
 370         return 0;
 371 }
 372 
 373 static int rx6110_remove(struct spi_device *spi)
 374 {
 375         return 0;
 376 }
 377 
 378 static const struct spi_device_id rx6110_id[] = {
 379         { "rx6110", 0 },
 380         { }
 381 };
 382 MODULE_DEVICE_TABLE(spi, rx6110_id);
 383 
 384 static const struct of_device_id rx6110_spi_of_match[] = {
 385         { .compatible = "epson,rx6110" },
 386         { },
 387 };
 388 MODULE_DEVICE_TABLE(of, rx6110_spi_of_match);
 389 
 390 static struct spi_driver rx6110_driver = {
 391         .driver = {
 392                 .name = RX6110_DRIVER_NAME,
 393                 .of_match_table = of_match_ptr(rx6110_spi_of_match),
 394         },
 395         .probe          = rx6110_probe,
 396         .remove         = rx6110_remove,
 397         .id_table       = rx6110_id,
 398 };
 399 
 400 module_spi_driver(rx6110_driver);
 401 
 402 MODULE_AUTHOR("Val Krutov <val.krutov@erd.epson.com>");
 403 MODULE_DESCRIPTION("RX-6110 SA RTC driver");
 404 MODULE_LICENSE("GPL");