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