Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.20-rc2 348 lines 10 kB view raw
1/* 2 * Real Time Clock driver for Marvell 88PM80x PMIC 3 * 4 * Copyright (c) 2012 Marvell International Ltd. 5 * Wenzeng Chen<wzch@marvell.com> 6 * Qiao Zhou <zhouqiao@marvell.com> 7 * 8 * This file is subject to the terms and conditions of the GNU General 9 * Public License. See the file "COPYING" in the main directory of this 10 * archive for more details. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22#include <linux/kernel.h> 23#include <linux/module.h> 24#include <linux/slab.h> 25#include <linux/regmap.h> 26#include <linux/mfd/core.h> 27#include <linux/mfd/88pm80x.h> 28#include <linux/rtc.h> 29 30#define PM800_RTC_COUNTER1 (0xD1) 31#define PM800_RTC_COUNTER2 (0xD2) 32#define PM800_RTC_COUNTER3 (0xD3) 33#define PM800_RTC_COUNTER4 (0xD4) 34#define PM800_RTC_EXPIRE1_1 (0xD5) 35#define PM800_RTC_EXPIRE1_2 (0xD6) 36#define PM800_RTC_EXPIRE1_3 (0xD7) 37#define PM800_RTC_EXPIRE1_4 (0xD8) 38#define PM800_RTC_TRIM1 (0xD9) 39#define PM800_RTC_TRIM2 (0xDA) 40#define PM800_RTC_TRIM3 (0xDB) 41#define PM800_RTC_TRIM4 (0xDC) 42#define PM800_RTC_EXPIRE2_1 (0xDD) 43#define PM800_RTC_EXPIRE2_2 (0xDE) 44#define PM800_RTC_EXPIRE2_3 (0xDF) 45#define PM800_RTC_EXPIRE2_4 (0xE0) 46 47#define PM800_POWER_DOWN_LOG1 (0xE5) 48#define PM800_POWER_DOWN_LOG2 (0xE6) 49 50struct pm80x_rtc_info { 51 struct pm80x_chip *chip; 52 struct regmap *map; 53 struct rtc_device *rtc_dev; 54 struct device *dev; 55 56 int irq; 57}; 58 59static irqreturn_t rtc_update_handler(int irq, void *data) 60{ 61 struct pm80x_rtc_info *info = (struct pm80x_rtc_info *)data; 62 int mask; 63 64 mask = PM800_ALARM | PM800_ALARM_WAKEUP; 65 regmap_update_bits(info->map, PM800_RTC_CONTROL, mask | PM800_ALARM1_EN, 66 mask); 67 rtc_update_irq(info->rtc_dev, 1, RTC_AF); 68 return IRQ_HANDLED; 69} 70 71static int pm80x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 72{ 73 struct pm80x_rtc_info *info = dev_get_drvdata(dev); 74 75 if (enabled) 76 regmap_update_bits(info->map, PM800_RTC_CONTROL, 77 PM800_ALARM1_EN, PM800_ALARM1_EN); 78 else 79 regmap_update_bits(info->map, PM800_RTC_CONTROL, 80 PM800_ALARM1_EN, 0); 81 return 0; 82} 83 84/* 85 * Calculate the next alarm time given the requested alarm time mask 86 * and the current time. 87 */ 88static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, 89 struct rtc_time *alrm) 90{ 91 unsigned long next_time; 92 unsigned long now_time; 93 94 next->tm_year = now->tm_year; 95 next->tm_mon = now->tm_mon; 96 next->tm_mday = now->tm_mday; 97 next->tm_hour = alrm->tm_hour; 98 next->tm_min = alrm->tm_min; 99 next->tm_sec = alrm->tm_sec; 100 101 now_time = rtc_tm_to_time64(now); 102 next_time = rtc_tm_to_time64(next); 103 104 if (next_time < now_time) { 105 /* Advance one day */ 106 next_time += 60 * 60 * 24; 107 rtc_time64_to_tm(next_time, next); 108 } 109} 110 111static int pm80x_rtc_read_time(struct device *dev, struct rtc_time *tm) 112{ 113 struct pm80x_rtc_info *info = dev_get_drvdata(dev); 114 unsigned char buf[4]; 115 unsigned long ticks, base, data; 116 regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4); 117 base = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 118 dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]); 119 120 /* load 32-bit read-only counter */ 121 regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4); 122 data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 123 ticks = base + data; 124 dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", 125 base, data, ticks); 126 rtc_time64_to_tm(ticks, tm); 127 return 0; 128} 129 130static int pm80x_rtc_set_time(struct device *dev, struct rtc_time *tm) 131{ 132 struct pm80x_rtc_info *info = dev_get_drvdata(dev); 133 unsigned char buf[4]; 134 unsigned long ticks, base, data; 135 136 ticks = rtc_tm_to_time64(tm); 137 138 /* load 32-bit read-only counter */ 139 regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4); 140 data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 141 base = ticks - data; 142 dev_dbg(info->dev, "set base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", 143 base, data, ticks); 144 buf[0] = base & 0xFF; 145 buf[1] = (base >> 8) & 0xFF; 146 buf[2] = (base >> 16) & 0xFF; 147 buf[3] = (base >> 24) & 0xFF; 148 regmap_raw_write(info->map, PM800_RTC_EXPIRE2_1, buf, 4); 149 150 return 0; 151} 152 153static int pm80x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 154{ 155 struct pm80x_rtc_info *info = dev_get_drvdata(dev); 156 unsigned char buf[4]; 157 unsigned long ticks, base, data; 158 int ret; 159 160 regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4); 161 base = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 162 dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]); 163 164 regmap_raw_read(info->map, PM800_RTC_EXPIRE1_1, buf, 4); 165 data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 166 ticks = base + data; 167 dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", 168 base, data, ticks); 169 170 rtc_time64_to_tm(ticks, &alrm->time); 171 regmap_read(info->map, PM800_RTC_CONTROL, &ret); 172 alrm->enabled = (ret & PM800_ALARM1_EN) ? 1 : 0; 173 alrm->pending = (ret & (PM800_ALARM | PM800_ALARM_WAKEUP)) ? 1 : 0; 174 return 0; 175} 176 177static int pm80x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 178{ 179 struct pm80x_rtc_info *info = dev_get_drvdata(dev); 180 struct rtc_time now_tm, alarm_tm; 181 unsigned long ticks, base, data; 182 unsigned char buf[4]; 183 int mask; 184 185 regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_ALARM1_EN, 0); 186 187 regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4); 188 base = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 189 dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]); 190 191 /* load 32-bit read-only counter */ 192 regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4); 193 data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 194 ticks = base + data; 195 dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", 196 base, data, ticks); 197 198 rtc_time64_to_tm(ticks, &now_tm); 199 dev_dbg(info->dev, "%s, now time : %lu\n", __func__, ticks); 200 rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); 201 /* get new ticks for alarm in 24 hours */ 202 ticks = rtc_tm_to_time64(&alarm_tm); 203 dev_dbg(info->dev, "%s, alarm time: %lu\n", __func__, ticks); 204 data = ticks - base; 205 206 buf[0] = data & 0xff; 207 buf[1] = (data >> 8) & 0xff; 208 buf[2] = (data >> 16) & 0xff; 209 buf[3] = (data >> 24) & 0xff; 210 regmap_raw_write(info->map, PM800_RTC_EXPIRE1_1, buf, 4); 211 if (alrm->enabled) { 212 mask = PM800_ALARM | PM800_ALARM_WAKEUP | PM800_ALARM1_EN; 213 regmap_update_bits(info->map, PM800_RTC_CONTROL, mask, mask); 214 } else { 215 mask = PM800_ALARM | PM800_ALARM_WAKEUP | PM800_ALARM1_EN; 216 regmap_update_bits(info->map, PM800_RTC_CONTROL, mask, 217 PM800_ALARM | PM800_ALARM_WAKEUP); 218 } 219 return 0; 220} 221 222static const struct rtc_class_ops pm80x_rtc_ops = { 223 .read_time = pm80x_rtc_read_time, 224 .set_time = pm80x_rtc_set_time, 225 .read_alarm = pm80x_rtc_read_alarm, 226 .set_alarm = pm80x_rtc_set_alarm, 227 .alarm_irq_enable = pm80x_rtc_alarm_irq_enable, 228}; 229 230#ifdef CONFIG_PM_SLEEP 231static int pm80x_rtc_suspend(struct device *dev) 232{ 233 return pm80x_dev_suspend(dev); 234} 235 236static int pm80x_rtc_resume(struct device *dev) 237{ 238 return pm80x_dev_resume(dev); 239} 240#endif 241 242static SIMPLE_DEV_PM_OPS(pm80x_rtc_pm_ops, pm80x_rtc_suspend, pm80x_rtc_resume); 243 244static int pm80x_rtc_probe(struct platform_device *pdev) 245{ 246 struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent); 247 struct pm80x_rtc_pdata *pdata = dev_get_platdata(&pdev->dev); 248 struct pm80x_rtc_info *info; 249 struct device_node *node = pdev->dev.of_node; 250 int ret; 251 252 if (!pdata && !node) { 253 dev_err(&pdev->dev, 254 "pm80x-rtc requires platform data or of_node\n"); 255 return -EINVAL; 256 } 257 258 if (!pdata) { 259 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 260 if (!pdata) { 261 dev_err(&pdev->dev, "failed to allocate memory\n"); 262 return -ENOMEM; 263 } 264 } 265 266 info = 267 devm_kzalloc(&pdev->dev, sizeof(struct pm80x_rtc_info), GFP_KERNEL); 268 if (!info) 269 return -ENOMEM; 270 info->irq = platform_get_irq(pdev, 0); 271 if (info->irq < 0) { 272 dev_err(&pdev->dev, "No IRQ resource!\n"); 273 ret = -EINVAL; 274 goto out; 275 } 276 277 info->chip = chip; 278 info->map = chip->regmap; 279 if (!info->map) { 280 dev_err(&pdev->dev, "no regmap!\n"); 281 ret = -EINVAL; 282 goto out; 283 } 284 285 info->dev = &pdev->dev; 286 dev_set_drvdata(&pdev->dev, info); 287 288 info->rtc_dev = devm_rtc_allocate_device(&pdev->dev); 289 if (IS_ERR(info->rtc_dev)) 290 return PTR_ERR(info->rtc_dev); 291 292 ret = pm80x_request_irq(chip, info->irq, rtc_update_handler, 293 IRQF_ONESHOT, "rtc", info); 294 if (ret < 0) { 295 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", 296 info->irq, ret); 297 goto out; 298 } 299 300 info->rtc_dev->ops = &pm80x_rtc_ops; 301 info->rtc_dev->range_max = U32_MAX; 302 303 ret = rtc_register_device(info->rtc_dev); 304 if (ret) { 305 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); 306 goto out_rtc; 307 } 308 /* 309 * enable internal XO instead of internal 3.25MHz clock since it can 310 * free running in PMIC power-down state. 311 */ 312 regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_RTC1_USE_XO, 313 PM800_RTC1_USE_XO); 314 315 /* remember whether this power up is caused by PMIC RTC or not */ 316 info->rtc_dev->dev.platform_data = &pdata->rtc_wakeup; 317 318 device_init_wakeup(&pdev->dev, 1); 319 320 return 0; 321out_rtc: 322 pm80x_free_irq(chip, info->irq, info); 323out: 324 return ret; 325} 326 327static int pm80x_rtc_remove(struct platform_device *pdev) 328{ 329 struct pm80x_rtc_info *info = platform_get_drvdata(pdev); 330 pm80x_free_irq(info->chip, info->irq, info); 331 return 0; 332} 333 334static struct platform_driver pm80x_rtc_driver = { 335 .driver = { 336 .name = "88pm80x-rtc", 337 .pm = &pm80x_rtc_pm_ops, 338 }, 339 .probe = pm80x_rtc_probe, 340 .remove = pm80x_rtc_remove, 341}; 342 343module_platform_driver(pm80x_rtc_driver); 344 345MODULE_LICENSE("GPL"); 346MODULE_DESCRIPTION("Marvell 88PM80x RTC driver"); 347MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>"); 348MODULE_ALIAS("platform:88pm80x-rtc");