root/drivers/rtc/rtc-pcf8583.c

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

DEFINITIONS

This source file includes following definitions.
  1. pcf8583_get_datetime
  2. pcf8583_set_datetime
  3. pcf8583_get_ctrl
  4. pcf8583_set_ctrl
  5. pcf8583_read_mem
  6. pcf8583_write_mem
  7. pcf8583_rtc_read_time
  8. pcf8583_rtc_set_time
  9. pcf8583_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  drivers/rtc/rtc-pcf8583.c
   4  *
   5  *  Copyright (C) 2000 Russell King
   6  *  Copyright (C) 2008 Wolfram Sang & Juergen Beisert, Pengutronix
   7  *
   8  *  Driver for PCF8583 RTC & RAM chip
   9  *
  10  *  Converted to the generic RTC susbsystem by G. Liakhovetski (2006)
  11  */
  12 #include <linux/module.h>
  13 #include <linux/i2c.h>
  14 #include <linux/slab.h>
  15 #include <linux/rtc.h>
  16 #include <linux/init.h>
  17 #include <linux/err.h>
  18 #include <linux/errno.h>
  19 #include <linux/bcd.h>
  20 
  21 struct rtc_mem {
  22         unsigned int    loc;
  23         unsigned int    nr;
  24         unsigned char   *data;
  25 };
  26 
  27 struct pcf8583 {
  28         struct rtc_device *rtc;
  29         unsigned char ctrl;
  30 };
  31 
  32 #define CTRL_STOP       0x80
  33 #define CTRL_HOLD       0x40
  34 #define CTRL_32KHZ      0x00
  35 #define CTRL_MASK       0x08
  36 #define CTRL_ALARMEN    0x04
  37 #define CTRL_ALARM      0x02
  38 #define CTRL_TIMER      0x01
  39 
  40 
  41 static struct i2c_driver pcf8583_driver;
  42 
  43 #define get_ctrl(x)    ((struct pcf8583 *)i2c_get_clientdata(x))->ctrl
  44 #define set_ctrl(x, v) get_ctrl(x) = v
  45 
  46 #define CMOS_YEAR       (64 + 128)
  47 #define CMOS_CHECKSUM   (63)
  48 
  49 static int pcf8583_get_datetime(struct i2c_client *client, struct rtc_time *dt)
  50 {
  51         unsigned char buf[8], addr[1] = { 1 };
  52         struct i2c_msg msgs[2] = {
  53                 {
  54                         .addr = client->addr,
  55                         .flags = 0,
  56                         .len = 1,
  57                         .buf = addr,
  58                 }, {
  59                         .addr = client->addr,
  60                         .flags = I2C_M_RD,
  61                         .len = 6,
  62                         .buf = buf,
  63                 }
  64         };
  65         int ret;
  66 
  67         memset(buf, 0, sizeof(buf));
  68 
  69         ret = i2c_transfer(client->adapter, msgs, 2);
  70         if (ret == 2) {
  71                 dt->tm_year = buf[4] >> 6;
  72                 dt->tm_wday = buf[5] >> 5;
  73 
  74                 buf[4] &= 0x3f;
  75                 buf[5] &= 0x1f;
  76 
  77                 dt->tm_sec = bcd2bin(buf[1]);
  78                 dt->tm_min = bcd2bin(buf[2]);
  79                 dt->tm_hour = bcd2bin(buf[3]);
  80                 dt->tm_mday = bcd2bin(buf[4]);
  81                 dt->tm_mon = bcd2bin(buf[5]) - 1;
  82         }
  83 
  84         return ret == 2 ? 0 : -EIO;
  85 }
  86 
  87 static int pcf8583_set_datetime(struct i2c_client *client, struct rtc_time *dt, int datetoo)
  88 {
  89         unsigned char buf[8];
  90         int ret, len = 6;
  91 
  92         buf[0] = 0;
  93         buf[1] = get_ctrl(client) | 0x80;
  94         buf[2] = 0;
  95         buf[3] = bin2bcd(dt->tm_sec);
  96         buf[4] = bin2bcd(dt->tm_min);
  97         buf[5] = bin2bcd(dt->tm_hour);
  98 
  99         if (datetoo) {
 100                 len = 8;
 101                 buf[6] = bin2bcd(dt->tm_mday) | (dt->tm_year << 6);
 102                 buf[7] = bin2bcd(dt->tm_mon + 1)  | (dt->tm_wday << 5);
 103         }
 104 
 105         ret = i2c_master_send(client, (char *)buf, len);
 106         if (ret != len)
 107                 return -EIO;
 108 
 109         buf[1] = get_ctrl(client);
 110         ret = i2c_master_send(client, (char *)buf, 2);
 111 
 112         return ret == 2 ? 0 : -EIO;
 113 }
 114 
 115 static int pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
 116 {
 117         *ctrl = get_ctrl(client);
 118         return 0;
 119 }
 120 
 121 static int pcf8583_set_ctrl(struct i2c_client *client, unsigned char *ctrl)
 122 {
 123         unsigned char buf[2];
 124 
 125         buf[0] = 0;
 126         buf[1] = *ctrl;
 127         set_ctrl(client, *ctrl);
 128 
 129         return i2c_master_send(client, (char *)buf, 2);
 130 }
 131 
 132 static int pcf8583_read_mem(struct i2c_client *client, struct rtc_mem *mem)
 133 {
 134         unsigned char addr[1];
 135         struct i2c_msg msgs[2] = {
 136                 {
 137                         .addr = client->addr,
 138                         .flags = 0,
 139                         .len = 1,
 140                         .buf = addr,
 141                 }, {
 142                         .addr = client->addr,
 143                         .flags = I2C_M_RD,
 144                         .len = mem->nr,
 145                         .buf = mem->data,
 146                 }
 147         };
 148 
 149         if (mem->loc < 8)
 150                 return -EINVAL;
 151 
 152         addr[0] = mem->loc;
 153 
 154         return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
 155 }
 156 
 157 static int pcf8583_write_mem(struct i2c_client *client, struct rtc_mem *mem)
 158 {
 159         unsigned char buf[9];
 160         int ret;
 161 
 162         if (mem->loc < 8 || mem->nr > 8)
 163                 return -EINVAL;
 164 
 165         buf[0] = mem->loc;
 166         memcpy(buf + 1, mem->data, mem->nr);
 167 
 168         ret = i2c_master_send(client, buf, mem->nr + 1);
 169         return ret == mem->nr + 1 ? 0 : -EIO;
 170 }
 171 
 172 static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm)
 173 {
 174         struct i2c_client *client = to_i2c_client(dev);
 175         unsigned char ctrl, year[2];
 176         struct rtc_mem mem = {
 177                 .loc = CMOS_YEAR,
 178                 .nr = sizeof(year),
 179                 .data = year
 180         };
 181         int real_year, year_offset, err;
 182 
 183         /*
 184          * Ensure that the RTC is running.
 185          */
 186         pcf8583_get_ctrl(client, &ctrl);
 187         if (ctrl & (CTRL_STOP | CTRL_HOLD)) {
 188                 unsigned char new_ctrl = ctrl & ~(CTRL_STOP | CTRL_HOLD);
 189 
 190                 dev_warn(dev, "resetting control %02x -> %02x\n",
 191                         ctrl, new_ctrl);
 192 
 193                 err = pcf8583_set_ctrl(client, &new_ctrl);
 194                 if (err < 0)
 195                         return err;
 196         }
 197 
 198         if (pcf8583_get_datetime(client, tm) ||
 199             pcf8583_read_mem(client, &mem))
 200                 return -EIO;
 201 
 202         real_year = year[0];
 203 
 204         /*
 205          * The RTC year holds the LSB two bits of the current
 206          * year, which should reflect the LSB two bits of the
 207          * CMOS copy of the year.  Any difference indicates
 208          * that we have to correct the CMOS version.
 209          */
 210         year_offset = tm->tm_year - (real_year & 3);
 211         if (year_offset < 0)
 212                 /*
 213                  * RTC year wrapped.  Adjust it appropriately.
 214                  */
 215                 year_offset += 4;
 216 
 217         tm->tm_year = (real_year + year_offset + year[1] * 100) - 1900;
 218 
 219         return 0;
 220 }
 221 
 222 static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm)
 223 {
 224         struct i2c_client *client = to_i2c_client(dev);
 225         unsigned char year[2], chk;
 226         struct rtc_mem cmos_year  = {
 227                 .loc = CMOS_YEAR,
 228                 .nr = sizeof(year),
 229                 .data = year
 230         };
 231         struct rtc_mem cmos_check = {
 232                 .loc = CMOS_CHECKSUM,
 233                 .nr = 1,
 234                 .data = &chk
 235         };
 236         unsigned int proper_year = tm->tm_year + 1900;
 237         int ret;
 238 
 239         /*
 240          * The RTC's own 2-bit year must reflect the least
 241          * significant two bits of the CMOS year.
 242          */
 243 
 244         ret = pcf8583_set_datetime(client, tm, 1);
 245         if (ret)
 246                 return ret;
 247 
 248         ret = pcf8583_read_mem(client, &cmos_check);
 249         if (ret)
 250                 return ret;
 251 
 252         ret = pcf8583_read_mem(client, &cmos_year);
 253         if (ret)
 254                 return ret;
 255 
 256         chk -= year[1] + year[0];
 257 
 258         year[1] = proper_year / 100;
 259         year[0] = proper_year % 100;
 260 
 261         chk += year[1] + year[0];
 262 
 263         ret = pcf8583_write_mem(client, &cmos_year);
 264 
 265         if (ret)
 266                 return ret;
 267 
 268         ret = pcf8583_write_mem(client, &cmos_check);
 269 
 270         return ret;
 271 }
 272 
 273 static const struct rtc_class_ops pcf8583_rtc_ops = {
 274         .read_time      = pcf8583_rtc_read_time,
 275         .set_time       = pcf8583_rtc_set_time,
 276 };
 277 
 278 static int pcf8583_probe(struct i2c_client *client,
 279                                 const struct i2c_device_id *id)
 280 {
 281         struct pcf8583 *pcf8583;
 282 
 283         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 284                 return -ENODEV;
 285 
 286         pcf8583 = devm_kzalloc(&client->dev, sizeof(struct pcf8583),
 287                                 GFP_KERNEL);
 288         if (!pcf8583)
 289                 return -ENOMEM;
 290 
 291         i2c_set_clientdata(client, pcf8583);
 292 
 293         pcf8583->rtc = devm_rtc_device_register(&client->dev,
 294                                 pcf8583_driver.driver.name,
 295                                 &pcf8583_rtc_ops, THIS_MODULE);
 296 
 297         return PTR_ERR_OR_ZERO(pcf8583->rtc);
 298 }
 299 
 300 static const struct i2c_device_id pcf8583_id[] = {
 301         { "pcf8583", 0 },
 302         { }
 303 };
 304 MODULE_DEVICE_TABLE(i2c, pcf8583_id);
 305 
 306 static struct i2c_driver pcf8583_driver = {
 307         .driver = {
 308                 .name   = "pcf8583",
 309         },
 310         .probe          = pcf8583_probe,
 311         .id_table       = pcf8583_id,
 312 };
 313 
 314 module_i2c_driver(pcf8583_driver);
 315 
 316 MODULE_AUTHOR("Russell King");
 317 MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
 318 MODULE_LICENSE("GPL");

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