Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * An I2C driver for the Intersil ISL 12026
0004  *
0005  * Copyright (c) 2018 Cavium, Inc.
0006  */
0007 #include <linux/bcd.h>
0008 #include <linux/delay.h>
0009 #include <linux/i2c.h>
0010 #include <linux/module.h>
0011 #include <linux/mutex.h>
0012 #include <linux/nvmem-provider.h>
0013 #include <linux/of.h>
0014 #include <linux/of_device.h>
0015 #include <linux/rtc.h>
0016 #include <linux/slab.h>
0017 
0018 /* register offsets */
0019 #define ISL12026_REG_PWR    0x14
0020 # define ISL12026_REG_PWR_BSW   BIT(6)
0021 # define ISL12026_REG_PWR_SBIB  BIT(7)
0022 #define ISL12026_REG_SC     0x30
0023 #define ISL12026_REG_HR     0x32
0024 # define ISL12026_REG_HR_MIL    BIT(7)  /* military or 24 hour time */
0025 #define ISL12026_REG_SR     0x3f
0026 # define ISL12026_REG_SR_RTCF   BIT(0)
0027 # define ISL12026_REG_SR_WEL    BIT(1)
0028 # define ISL12026_REG_SR_RWEL   BIT(2)
0029 # define ISL12026_REG_SR_MBZ    BIT(3)
0030 # define ISL12026_REG_SR_OSCF   BIT(4)
0031 
0032 /* The EEPROM array responds at i2c address 0x57 */
0033 #define ISL12026_EEPROM_ADDR    0x57
0034 
0035 #define ISL12026_PAGESIZE 16
0036 #define ISL12026_NVMEM_WRITE_TIME 20
0037 
0038 struct isl12026 {
0039     struct rtc_device *rtc;
0040     struct i2c_client *nvm_client;
0041 };
0042 
0043 static int isl12026_read_reg(struct i2c_client *client, int reg)
0044 {
0045     u8 addr[] = {0, reg};
0046     u8 val;
0047     int ret;
0048 
0049     struct i2c_msg msgs[] = {
0050         {
0051             .addr   = client->addr,
0052             .flags  = 0,
0053             .len    = sizeof(addr),
0054             .buf    = addr
0055         }, {
0056             .addr   = client->addr,
0057             .flags  = I2C_M_RD,
0058             .len    = 1,
0059             .buf    = &val
0060         }
0061     };
0062 
0063     ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
0064     if (ret != ARRAY_SIZE(msgs)) {
0065         dev_err(&client->dev, "read reg error, ret=%d\n", ret);
0066         ret = ret < 0 ? ret : -EIO;
0067     } else {
0068         ret = val;
0069     }
0070 
0071     return ret;
0072 }
0073 
0074 static int isl12026_arm_write(struct i2c_client *client)
0075 {
0076     int ret;
0077     u8 op[3];
0078     struct i2c_msg msg = {
0079         .addr   = client->addr,
0080         .flags  = 0,
0081         .len    = 1,
0082         .buf    = op
0083     };
0084 
0085     /* Set SR.WEL */
0086     op[0] = 0;
0087     op[1] = ISL12026_REG_SR;
0088     op[2] = ISL12026_REG_SR_WEL;
0089     msg.len = 3;
0090     ret = i2c_transfer(client->adapter, &msg, 1);
0091     if (ret != 1) {
0092         dev_err(&client->dev, "write error SR.WEL, ret=%d\n", ret);
0093         ret = ret < 0 ? ret : -EIO;
0094         goto out;
0095     }
0096 
0097     /* Set SR.WEL and SR.RWEL */
0098     op[2] = ISL12026_REG_SR_WEL | ISL12026_REG_SR_RWEL;
0099     msg.len = 3;
0100     ret = i2c_transfer(client->adapter, &msg, 1);
0101     if (ret != 1) {
0102         dev_err(&client->dev,
0103             "write error SR.WEL|SR.RWEL, ret=%d\n", ret);
0104         ret = ret < 0 ? ret : -EIO;
0105         goto out;
0106     } else {
0107         ret = 0;
0108     }
0109 out:
0110     return ret;
0111 }
0112 
0113 static int isl12026_disarm_write(struct i2c_client *client)
0114 {
0115     int ret;
0116     u8 op[3] = {0, ISL12026_REG_SR, 0};
0117     struct i2c_msg msg = {
0118         .addr   = client->addr,
0119         .flags  = 0,
0120         .len    = sizeof(op),
0121         .buf    = op
0122     };
0123 
0124     ret = i2c_transfer(client->adapter, &msg, 1);
0125     if (ret != 1) {
0126         dev_err(&client->dev,
0127             "write error SR, ret=%d\n", ret);
0128         ret = ret < 0 ? ret : -EIO;
0129     } else {
0130         ret = 0;
0131     }
0132 
0133     return ret;
0134 }
0135 
0136 static int isl12026_write_reg(struct i2c_client *client, int reg, u8 val)
0137 {
0138     int ret;
0139     u8 op[3] = {0, reg, val};
0140     struct i2c_msg msg = {
0141         .addr   = client->addr,
0142         .flags  = 0,
0143         .len    = sizeof(op),
0144         .buf    = op
0145     };
0146 
0147     ret = isl12026_arm_write(client);
0148     if (ret)
0149         return ret;
0150 
0151     ret = i2c_transfer(client->adapter, &msg, 1);
0152     if (ret != 1) {
0153         dev_err(&client->dev, "write error CCR, ret=%d\n", ret);
0154         ret = ret < 0 ? ret : -EIO;
0155         goto out;
0156     }
0157 
0158     msleep(ISL12026_NVMEM_WRITE_TIME);
0159 
0160     ret = isl12026_disarm_write(client);
0161 out:
0162     return ret;
0163 }
0164 
0165 static int isl12026_rtc_set_time(struct device *dev, struct rtc_time *tm)
0166 {
0167     struct i2c_client *client = to_i2c_client(dev);
0168     int ret;
0169     u8 op[10];
0170     struct i2c_msg msg = {
0171         .addr   = client->addr,
0172         .flags  = 0,
0173         .len    = sizeof(op),
0174         .buf    = op
0175     };
0176 
0177     ret = isl12026_arm_write(client);
0178     if (ret)
0179         return ret;
0180 
0181     /* Set the CCR registers */
0182     op[0] = 0;
0183     op[1] = ISL12026_REG_SC;
0184     op[2] = bin2bcd(tm->tm_sec); /* SC */
0185     op[3] = bin2bcd(tm->tm_min); /* MN */
0186     op[4] = bin2bcd(tm->tm_hour) | ISL12026_REG_HR_MIL; /* HR */
0187     op[5] = bin2bcd(tm->tm_mday); /* DT */
0188     op[6] = bin2bcd(tm->tm_mon + 1); /* MO */
0189     op[7] = bin2bcd(tm->tm_year % 100); /* YR */
0190     op[8] = bin2bcd(tm->tm_wday & 7); /* DW */
0191     op[9] = bin2bcd(tm->tm_year >= 100 ? 20 : 19); /* Y2K */
0192     ret = i2c_transfer(client->adapter, &msg, 1);
0193     if (ret != 1) {
0194         dev_err(&client->dev, "write error CCR, ret=%d\n", ret);
0195         ret = ret < 0 ? ret : -EIO;
0196         goto out;
0197     }
0198 
0199     ret = isl12026_disarm_write(client);
0200 out:
0201     return ret;
0202 }
0203 
0204 static int isl12026_rtc_read_time(struct device *dev, struct rtc_time *tm)
0205 {
0206     struct i2c_client *client = to_i2c_client(dev);
0207     u8 ccr[8];
0208     u8 addr[2];
0209     u8 sr;
0210     int ret;
0211     struct i2c_msg msgs[] = {
0212         {
0213             .addr   = client->addr,
0214             .flags  = 0,
0215             .len    = sizeof(addr),
0216             .buf    = addr
0217         }, {
0218             .addr   = client->addr,
0219             .flags  = I2C_M_RD,
0220         }
0221     };
0222 
0223     /* First, read SR */
0224     addr[0] = 0;
0225     addr[1] = ISL12026_REG_SR;
0226     msgs[1].len = 1;
0227     msgs[1].buf = &sr;
0228 
0229     ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
0230     if (ret != ARRAY_SIZE(msgs)) {
0231         dev_err(&client->dev, "read error, ret=%d\n", ret);
0232         ret = ret < 0 ? ret : -EIO;
0233         goto out;
0234     }
0235 
0236     if (sr & ISL12026_REG_SR_RTCF)
0237         dev_warn(&client->dev, "Real-Time Clock Failure on read\n");
0238     if (sr & ISL12026_REG_SR_OSCF)
0239         dev_warn(&client->dev, "Oscillator Failure on read\n");
0240 
0241     /* Second, CCR regs */
0242     addr[0] = 0;
0243     addr[1] = ISL12026_REG_SC;
0244     msgs[1].len = sizeof(ccr);
0245     msgs[1].buf = ccr;
0246 
0247     ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
0248     if (ret != ARRAY_SIZE(msgs)) {
0249         dev_err(&client->dev, "read error, ret=%d\n", ret);
0250         ret = ret < 0 ? ret : -EIO;
0251         goto out;
0252     }
0253 
0254     tm->tm_sec = bcd2bin(ccr[0] & 0x7F);
0255     tm->tm_min = bcd2bin(ccr[1] & 0x7F);
0256     if (ccr[2] & ISL12026_REG_HR_MIL)
0257         tm->tm_hour = bcd2bin(ccr[2] & 0x3F);
0258     else
0259         tm->tm_hour = bcd2bin(ccr[2] & 0x1F) +
0260             ((ccr[2] & 0x20) ? 12 : 0);
0261     tm->tm_mday = bcd2bin(ccr[3] & 0x3F);
0262     tm->tm_mon = bcd2bin(ccr[4] & 0x1F) - 1;
0263     tm->tm_year = bcd2bin(ccr[5]);
0264     if (bcd2bin(ccr[7]) == 20)
0265         tm->tm_year += 100;
0266     tm->tm_wday = ccr[6] & 0x07;
0267 
0268     ret = 0;
0269 out:
0270     return ret;
0271 }
0272 
0273 static const struct rtc_class_ops isl12026_rtc_ops = {
0274     .read_time  = isl12026_rtc_read_time,
0275     .set_time   = isl12026_rtc_set_time,
0276 };
0277 
0278 static int isl12026_nvm_read(void *p, unsigned int offset,
0279                  void *val, size_t bytes)
0280 {
0281     struct isl12026 *priv = p;
0282     int ret;
0283     u8 addr[2];
0284     struct i2c_msg msgs[] = {
0285         {
0286             .addr   = priv->nvm_client->addr,
0287             .flags  = 0,
0288             .len    = sizeof(addr),
0289             .buf    = addr
0290         }, {
0291             .addr   = priv->nvm_client->addr,
0292             .flags  = I2C_M_RD,
0293             .buf    = val
0294         }
0295     };
0296 
0297     /*
0298      * offset and bytes checked and limited by nvmem core, so
0299      * proceed without further checks.
0300      */
0301     ret = mutex_lock_interruptible(&priv->rtc->ops_lock);
0302     if (ret)
0303         return ret;
0304 
0305     /* 2 bytes of address, most significant first */
0306     addr[0] = offset >> 8;
0307     addr[1] = offset;
0308     msgs[1].len = bytes;
0309     ret = i2c_transfer(priv->nvm_client->adapter, msgs, ARRAY_SIZE(msgs));
0310 
0311     mutex_unlock(&priv->rtc->ops_lock);
0312 
0313     if (ret != ARRAY_SIZE(msgs)) {
0314         dev_err(&priv->nvm_client->dev,
0315             "nvmem read error, ret=%d\n", ret);
0316         return ret < 0 ? ret : -EIO;
0317     }
0318 
0319     return 0;
0320 }
0321 
0322 static int isl12026_nvm_write(void *p, unsigned int offset,
0323                   void *val, size_t bytes)
0324 {
0325     struct isl12026 *priv = p;
0326     int ret;
0327     u8 *v = val;
0328     size_t chunk_size, num_written;
0329     u8 payload[ISL12026_PAGESIZE + 2]; /* page + 2 address bytes */
0330     struct i2c_msg msgs[] = {
0331         {
0332             .addr   = priv->nvm_client->addr,
0333             .flags  = 0,
0334             .buf    = payload
0335         }
0336     };
0337 
0338     /*
0339      * offset and bytes checked and limited by nvmem core, so
0340      * proceed without further checks.
0341      */
0342     ret = mutex_lock_interruptible(&priv->rtc->ops_lock);
0343     if (ret)
0344         return ret;
0345 
0346     num_written = 0;
0347     while (bytes) {
0348         chunk_size = round_down(offset, ISL12026_PAGESIZE) +
0349             ISL12026_PAGESIZE - offset;
0350         chunk_size = min(bytes, chunk_size);
0351         /*
0352          * 2 bytes of address, most significant first, followed
0353          * by page data bytes
0354          */
0355         memcpy(payload + 2, v + num_written, chunk_size);
0356         payload[0] = offset >> 8;
0357         payload[1] = offset;
0358         msgs[0].len = chunk_size + 2;
0359         ret = i2c_transfer(priv->nvm_client->adapter,
0360                    msgs, ARRAY_SIZE(msgs));
0361         if (ret != ARRAY_SIZE(msgs)) {
0362             dev_err(&priv->nvm_client->dev,
0363                 "nvmem write error, ret=%d\n", ret);
0364             ret = ret < 0 ? ret : -EIO;
0365             break;
0366         }
0367         ret = 0;
0368         bytes -= chunk_size;
0369         offset += chunk_size;
0370         num_written += chunk_size;
0371         msleep(ISL12026_NVMEM_WRITE_TIME);
0372     }
0373 
0374     mutex_unlock(&priv->rtc->ops_lock);
0375 
0376     return ret;
0377 }
0378 
0379 static void isl12026_force_power_modes(struct i2c_client *client)
0380 {
0381     int ret;
0382     int pwr, requested_pwr;
0383     u32 bsw_val, sbib_val;
0384     bool set_bsw, set_sbib;
0385 
0386     /*
0387      * If we can read the of_property, set the specified value.
0388      * If there is an error reading the of_property (likely
0389      * because it does not exist), keep the current value.
0390      */
0391     ret = of_property_read_u32(client->dev.of_node,
0392                    "isil,pwr-bsw", &bsw_val);
0393     set_bsw = (ret == 0);
0394 
0395     ret = of_property_read_u32(client->dev.of_node,
0396                    "isil,pwr-sbib", &sbib_val);
0397     set_sbib = (ret == 0);
0398 
0399     /* Check if PWR.BSW and/or PWR.SBIB need specified values */
0400     if (!set_bsw && !set_sbib)
0401         return;
0402 
0403     pwr = isl12026_read_reg(client, ISL12026_REG_PWR);
0404     if (pwr < 0) {
0405         dev_warn(&client->dev, "Error: Failed to read PWR %d\n", pwr);
0406         return;
0407     }
0408 
0409     requested_pwr = pwr;
0410 
0411     if (set_bsw) {
0412         if (bsw_val)
0413             requested_pwr |= ISL12026_REG_PWR_BSW;
0414         else
0415             requested_pwr &= ~ISL12026_REG_PWR_BSW;
0416     } /* else keep current BSW */
0417 
0418     if (set_sbib) {
0419         if (sbib_val)
0420             requested_pwr |= ISL12026_REG_PWR_SBIB;
0421         else
0422             requested_pwr &= ~ISL12026_REG_PWR_SBIB;
0423     } /* else keep current SBIB */
0424 
0425     if (pwr >= 0 && pwr != requested_pwr) {
0426         dev_dbg(&client->dev, "PWR: %02x\n", pwr);
0427         dev_dbg(&client->dev, "Updating PWR to: %02x\n", requested_pwr);
0428         isl12026_write_reg(client, ISL12026_REG_PWR, requested_pwr);
0429     }
0430 }
0431 
0432 static int isl12026_probe_new(struct i2c_client *client)
0433 {
0434     struct isl12026 *priv;
0435     int ret;
0436     struct nvmem_config nvm_cfg = {
0437         .name = "isl12026-",
0438         .base_dev = &client->dev,
0439         .stride = 1,
0440         .word_size = 1,
0441         .size = 512,
0442         .reg_read = isl12026_nvm_read,
0443         .reg_write = isl12026_nvm_write,
0444     };
0445 
0446     if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
0447         return -ENODEV;
0448 
0449     priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
0450     if (!priv)
0451         return -ENOMEM;
0452 
0453     i2c_set_clientdata(client, priv);
0454 
0455     isl12026_force_power_modes(client);
0456 
0457     priv->nvm_client = i2c_new_dummy_device(client->adapter, ISL12026_EEPROM_ADDR);
0458     if (IS_ERR(priv->nvm_client))
0459         return PTR_ERR(priv->nvm_client);
0460 
0461     priv->rtc = devm_rtc_allocate_device(&client->dev);
0462     ret = PTR_ERR_OR_ZERO(priv->rtc);
0463     if (ret)
0464         return ret;
0465 
0466     priv->rtc->ops = &isl12026_rtc_ops;
0467     nvm_cfg.priv = priv;
0468     ret = devm_rtc_nvmem_register(priv->rtc, &nvm_cfg);
0469     if (ret)
0470         return ret;
0471 
0472     return devm_rtc_register_device(priv->rtc);
0473 }
0474 
0475 static int isl12026_remove(struct i2c_client *client)
0476 {
0477     struct isl12026 *priv = i2c_get_clientdata(client);
0478 
0479     i2c_unregister_device(priv->nvm_client);
0480     return 0;
0481 }
0482 
0483 static const struct of_device_id isl12026_dt_match[] = {
0484     { .compatible = "isil,isl12026" },
0485     { }
0486 };
0487 MODULE_DEVICE_TABLE(of, isl12026_dt_match);
0488 
0489 static struct i2c_driver isl12026_driver = {
0490     .driver     = {
0491         .name   = "rtc-isl12026",
0492         .of_match_table = isl12026_dt_match,
0493     },
0494     .probe_new  = isl12026_probe_new,
0495     .remove     = isl12026_remove,
0496 };
0497 
0498 module_i2c_driver(isl12026_driver);
0499 
0500 MODULE_DESCRIPTION("ISL 12026 RTC driver");
0501 MODULE_LICENSE("GPL");