root/drivers/rtc/rtc-pcf8523.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pcf8523_read
  2. pcf8523_write
  3. pcf8523_voltage_low
  4. pcf8523_load_capacitance
  5. pcf8523_set_pm
  6. pcf8523_stop_rtc
  7. pcf8523_start_rtc
  8. pcf8523_rtc_read_time
  9. pcf8523_rtc_set_time
  10. pcf8523_rtc_ioctl
  11. pcf8523_rtc_read_offset
  12. pcf8523_rtc_set_offset
  13. pcf8523_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2012 Avionic Design GmbH
   4  */
   5 
   6 #include <linux/bcd.h>
   7 #include <linux/i2c.h>
   8 #include <linux/module.h>
   9 #include <linux/rtc.h>
  10 #include <linux/of.h>
  11 
  12 #define DRIVER_NAME "rtc-pcf8523"
  13 
  14 #define REG_CONTROL1 0x00
  15 #define REG_CONTROL1_CAP_SEL (1 << 7)
  16 #define REG_CONTROL1_STOP    (1 << 5)
  17 
  18 #define REG_CONTROL3 0x02
  19 #define REG_CONTROL3_PM_BLD (1 << 7) /* battery low detection disabled */
  20 #define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */
  21 #define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */
  22 #define REG_CONTROL3_PM_MASK 0xe0
  23 #define REG_CONTROL3_BLF (1 << 2) /* battery low bit, read-only */
  24 
  25 #define REG_SECONDS  0x03
  26 #define REG_SECONDS_OS (1 << 7)
  27 
  28 #define REG_MINUTES  0x04
  29 #define REG_HOURS    0x05
  30 #define REG_DAYS     0x06
  31 #define REG_WEEKDAYS 0x07
  32 #define REG_MONTHS   0x08
  33 #define REG_YEARS    0x09
  34 
  35 #define REG_OFFSET   0x0e
  36 #define REG_OFFSET_MODE BIT(7)
  37 
  38 struct pcf8523 {
  39         struct rtc_device *rtc;
  40 };
  41 
  42 static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep)
  43 {
  44         struct i2c_msg msgs[2];
  45         u8 value = 0;
  46         int err;
  47 
  48         msgs[0].addr = client->addr;
  49         msgs[0].flags = 0;
  50         msgs[0].len = sizeof(reg);
  51         msgs[0].buf = &reg;
  52 
  53         msgs[1].addr = client->addr;
  54         msgs[1].flags = I2C_M_RD;
  55         msgs[1].len = sizeof(value);
  56         msgs[1].buf = &value;
  57 
  58         err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  59         if (err < 0)
  60                 return err;
  61 
  62         *valuep = value;
  63 
  64         return 0;
  65 }
  66 
  67 static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value)
  68 {
  69         u8 buffer[2] = { reg, value };
  70         struct i2c_msg msg;
  71         int err;
  72 
  73         msg.addr = client->addr;
  74         msg.flags = 0;
  75         msg.len = sizeof(buffer);
  76         msg.buf = buffer;
  77 
  78         err = i2c_transfer(client->adapter, &msg, 1);
  79         if (err < 0)
  80                 return err;
  81 
  82         return 0;
  83 }
  84 
  85 static int pcf8523_voltage_low(struct i2c_client *client)
  86 {
  87         u8 value;
  88         int err;
  89 
  90         err = pcf8523_read(client, REG_CONTROL3, &value);
  91         if (err < 0)
  92                 return err;
  93 
  94         return !!(value & REG_CONTROL3_BLF);
  95 }
  96 
  97 static int pcf8523_load_capacitance(struct i2c_client *client)
  98 {
  99         u32 load;
 100         u8 value;
 101         int err;
 102 
 103         err = pcf8523_read(client, REG_CONTROL1, &value);
 104         if (err < 0)
 105                 return err;
 106 
 107         load = 12500;
 108         of_property_read_u32(client->dev.of_node, "quartz-load-femtofarads",
 109                              &load);
 110 
 111         switch (load) {
 112         default:
 113                 dev_warn(&client->dev, "Unknown quartz-load-femtofarads value: %d. Assuming 12500",
 114                          load);
 115                 /* fall through */
 116         case 12500:
 117                 value |= REG_CONTROL1_CAP_SEL;
 118                 break;
 119         case 7000:
 120                 value &= ~REG_CONTROL1_CAP_SEL;
 121                 break;
 122         }
 123 
 124         err = pcf8523_write(client, REG_CONTROL1, value);
 125 
 126         return err;
 127 }
 128 
 129 static int pcf8523_set_pm(struct i2c_client *client, u8 pm)
 130 {
 131         u8 value;
 132         int err;
 133 
 134         err = pcf8523_read(client, REG_CONTROL3, &value);
 135         if (err < 0)
 136                 return err;
 137 
 138         value = (value & ~REG_CONTROL3_PM_MASK) | pm;
 139 
 140         err = pcf8523_write(client, REG_CONTROL3, value);
 141         if (err < 0)
 142                 return err;
 143 
 144         return 0;
 145 }
 146 
 147 static int pcf8523_stop_rtc(struct i2c_client *client)
 148 {
 149         u8 value;
 150         int err;
 151 
 152         err = pcf8523_read(client, REG_CONTROL1, &value);
 153         if (err < 0)
 154                 return err;
 155 
 156         value |= REG_CONTROL1_STOP;
 157 
 158         err = pcf8523_write(client, REG_CONTROL1, value);
 159         if (err < 0)
 160                 return err;
 161 
 162         return 0;
 163 }
 164 
 165 static int pcf8523_start_rtc(struct i2c_client *client)
 166 {
 167         u8 value;
 168         int err;
 169 
 170         err = pcf8523_read(client, REG_CONTROL1, &value);
 171         if (err < 0)
 172                 return err;
 173 
 174         value &= ~REG_CONTROL1_STOP;
 175 
 176         err = pcf8523_write(client, REG_CONTROL1, value);
 177         if (err < 0)
 178                 return err;
 179 
 180         return 0;
 181 }
 182 
 183 static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
 184 {
 185         struct i2c_client *client = to_i2c_client(dev);
 186         u8 start = REG_SECONDS, regs[7];
 187         struct i2c_msg msgs[2];
 188         int err;
 189 
 190         err = pcf8523_voltage_low(client);
 191         if (err < 0) {
 192                 return err;
 193         } else if (err > 0) {
 194                 dev_err(dev, "low voltage detected, time is unreliable\n");
 195                 return -EINVAL;
 196         }
 197 
 198         msgs[0].addr = client->addr;
 199         msgs[0].flags = 0;
 200         msgs[0].len = 1;
 201         msgs[0].buf = &start;
 202 
 203         msgs[1].addr = client->addr;
 204         msgs[1].flags = I2C_M_RD;
 205         msgs[1].len = sizeof(regs);
 206         msgs[1].buf = regs;
 207 
 208         err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
 209         if (err < 0)
 210                 return err;
 211 
 212         if (regs[0] & REG_SECONDS_OS)
 213                 return -EINVAL;
 214 
 215         tm->tm_sec = bcd2bin(regs[0] & 0x7f);
 216         tm->tm_min = bcd2bin(regs[1] & 0x7f);
 217         tm->tm_hour = bcd2bin(regs[2] & 0x3f);
 218         tm->tm_mday = bcd2bin(regs[3] & 0x3f);
 219         tm->tm_wday = regs[4] & 0x7;
 220         tm->tm_mon = bcd2bin(regs[5] & 0x1f) - 1;
 221         tm->tm_year = bcd2bin(regs[6]) + 100;
 222 
 223         return 0;
 224 }
 225 
 226 static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
 227 {
 228         struct i2c_client *client = to_i2c_client(dev);
 229         struct i2c_msg msg;
 230         u8 regs[8];
 231         int err;
 232 
 233         /*
 234          * The hardware can only store values between 0 and 99 in it's YEAR
 235          * register (with 99 overflowing to 0 on increment).
 236          * After 2100-02-28 we could start interpreting the year to be in the
 237          * interval [2100, 2199], but there is no path to switch in a smooth way
 238          * because the chip handles YEAR=0x00 (and the out-of-spec
 239          * YEAR=0xa0) as a leap year, but 2100 isn't.
 240          */
 241         if (tm->tm_year < 100 || tm->tm_year >= 200)
 242                 return -EINVAL;
 243 
 244         err = pcf8523_stop_rtc(client);
 245         if (err < 0)
 246                 return err;
 247 
 248         regs[0] = REG_SECONDS;
 249         /* This will purposely overwrite REG_SECONDS_OS */
 250         regs[1] = bin2bcd(tm->tm_sec);
 251         regs[2] = bin2bcd(tm->tm_min);
 252         regs[3] = bin2bcd(tm->tm_hour);
 253         regs[4] = bin2bcd(tm->tm_mday);
 254         regs[5] = tm->tm_wday;
 255         regs[6] = bin2bcd(tm->tm_mon + 1);
 256         regs[7] = bin2bcd(tm->tm_year - 100);
 257 
 258         msg.addr = client->addr;
 259         msg.flags = 0;
 260         msg.len = sizeof(regs);
 261         msg.buf = regs;
 262 
 263         err = i2c_transfer(client->adapter, &msg, 1);
 264         if (err < 0) {
 265                 /*
 266                  * If the time cannot be set, restart the RTC anyway. Note
 267                  * that errors are ignored if the RTC cannot be started so
 268                  * that we have a chance to propagate the original error.
 269                  */
 270                 pcf8523_start_rtc(client);
 271                 return err;
 272         }
 273 
 274         return pcf8523_start_rtc(client);
 275 }
 276 
 277 #ifdef CONFIG_RTC_INTF_DEV
 278 static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
 279                              unsigned long arg)
 280 {
 281         struct i2c_client *client = to_i2c_client(dev);
 282         int ret;
 283 
 284         switch (cmd) {
 285         case RTC_VL_READ:
 286                 ret = pcf8523_voltage_low(client);
 287                 if (ret < 0)
 288                         return ret;
 289 
 290                 if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
 291                         return -EFAULT;
 292 
 293                 return 0;
 294         default:
 295                 return -ENOIOCTLCMD;
 296         }
 297 }
 298 #else
 299 #define pcf8523_rtc_ioctl NULL
 300 #endif
 301 
 302 static int pcf8523_rtc_read_offset(struct device *dev, long *offset)
 303 {
 304         struct i2c_client *client = to_i2c_client(dev);
 305         int err;
 306         u8 value;
 307         s8 val;
 308 
 309         err = pcf8523_read(client, REG_OFFSET, &value);
 310         if (err < 0)
 311                 return err;
 312 
 313         /* sign extend the 7-bit offset value */
 314         val = value << 1;
 315         *offset = (value & REG_OFFSET_MODE ? 4069 : 4340) * (val >> 1);
 316 
 317         return 0;
 318 }
 319 
 320 static int pcf8523_rtc_set_offset(struct device *dev, long offset)
 321 {
 322         struct i2c_client *client = to_i2c_client(dev);
 323         long reg_m0, reg_m1;
 324         u8 value;
 325 
 326         reg_m0 = clamp(DIV_ROUND_CLOSEST(offset, 4340), -64L, 63L);
 327         reg_m1 = clamp(DIV_ROUND_CLOSEST(offset, 4069), -64L, 63L);
 328 
 329         if (abs(reg_m0 * 4340 - offset) < abs(reg_m1 * 4069 - offset))
 330                 value = reg_m0 & 0x7f;
 331         else
 332                 value = (reg_m1 & 0x7f) | REG_OFFSET_MODE;
 333 
 334         return pcf8523_write(client, REG_OFFSET, value);
 335 }
 336 
 337 static const struct rtc_class_ops pcf8523_rtc_ops = {
 338         .read_time = pcf8523_rtc_read_time,
 339         .set_time = pcf8523_rtc_set_time,
 340         .ioctl = pcf8523_rtc_ioctl,
 341         .read_offset = pcf8523_rtc_read_offset,
 342         .set_offset = pcf8523_rtc_set_offset,
 343 };
 344 
 345 static int pcf8523_probe(struct i2c_client *client,
 346                          const struct i2c_device_id *id)
 347 {
 348         struct pcf8523 *pcf;
 349         int err;
 350 
 351         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 352                 return -ENODEV;
 353 
 354         pcf = devm_kzalloc(&client->dev, sizeof(*pcf), GFP_KERNEL);
 355         if (!pcf)
 356                 return -ENOMEM;
 357 
 358         err = pcf8523_load_capacitance(client);
 359         if (err < 0)
 360                 dev_warn(&client->dev, "failed to set xtal load capacitance: %d",
 361                          err);
 362 
 363         err = pcf8523_set_pm(client, 0);
 364         if (err < 0)
 365                 return err;
 366 
 367         pcf->rtc = devm_rtc_device_register(&client->dev, DRIVER_NAME,
 368                                        &pcf8523_rtc_ops, THIS_MODULE);
 369         if (IS_ERR(pcf->rtc))
 370                 return PTR_ERR(pcf->rtc);
 371 
 372         i2c_set_clientdata(client, pcf);
 373 
 374         return 0;
 375 }
 376 
 377 static const struct i2c_device_id pcf8523_id[] = {
 378         { "pcf8523", 0 },
 379         { }
 380 };
 381 MODULE_DEVICE_TABLE(i2c, pcf8523_id);
 382 
 383 #ifdef CONFIG_OF
 384 static const struct of_device_id pcf8523_of_match[] = {
 385         { .compatible = "nxp,pcf8523" },
 386         { .compatible = "microcrystal,rv8523" },
 387         { }
 388 };
 389 MODULE_DEVICE_TABLE(of, pcf8523_of_match);
 390 #endif
 391 
 392 static struct i2c_driver pcf8523_driver = {
 393         .driver = {
 394                 .name = DRIVER_NAME,
 395                 .of_match_table = of_match_ptr(pcf8523_of_match),
 396         },
 397         .probe = pcf8523_probe,
 398         .id_table = pcf8523_id,
 399 };
 400 module_i2c_driver(pcf8523_driver);
 401 
 402 MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
 403 MODULE_DESCRIPTION("NXP PCF8523 RTC driver");
 404 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */