Lines Matching +full:meson6 +full:- +full:rtc
1 // SPDX-License-Identifier: GPL-2.0
3 * RTC driver for the interal RTC block in the Amlogic Meson6, Meson8,
6 * The RTC is split in to two parts, the AHB front end and a simple serial
19 #include <linux/nvmem-provider.h>
25 #include <linux/rtc.h>
46 /* rtc registers accessed via rtc-serial interface */
70 .name = "peripheral-registers",
77 /* RTC front-end serialiser controls */
79 static void meson_rtc_sclk_pulse(struct meson_rtc *rtc) in meson_rtc_sclk_pulse() argument
82 regmap_update_bits(rtc->peripheral, RTC_ADDR0, RTC_ADDR0_LINE_SCLK, 0); in meson_rtc_sclk_pulse()
84 regmap_update_bits(rtc->peripheral, RTC_ADDR0, RTC_ADDR0_LINE_SCLK, in meson_rtc_sclk_pulse()
88 static void meson_rtc_send_bit(struct meson_rtc *rtc, unsigned int bit) in meson_rtc_send_bit() argument
90 regmap_update_bits(rtc->peripheral, RTC_ADDR0, RTC_ADDR0_LINE_SDI, in meson_rtc_send_bit()
92 meson_rtc_sclk_pulse(rtc); in meson_rtc_send_bit()
95 static void meson_rtc_send_bits(struct meson_rtc *rtc, u32 data, in meson_rtc_send_bits() argument
98 u32 bit = 1 << (nr - 1); in meson_rtc_send_bits()
101 meson_rtc_send_bit(rtc, data & bit); in meson_rtc_send_bits()
106 static void meson_rtc_set_dir(struct meson_rtc *rtc, u32 mode) in meson_rtc_set_dir() argument
108 regmap_update_bits(rtc->peripheral, RTC_ADDR0, RTC_ADDR0_LINE_SEN, 0); in meson_rtc_set_dir()
109 regmap_update_bits(rtc->peripheral, RTC_ADDR0, RTC_ADDR0_LINE_SDI, 0); in meson_rtc_set_dir()
110 meson_rtc_send_bit(rtc, mode); in meson_rtc_set_dir()
111 regmap_update_bits(rtc->peripheral, RTC_ADDR0, RTC_ADDR0_LINE_SDI, 0); in meson_rtc_set_dir()
114 static u32 meson_rtc_get_data(struct meson_rtc *rtc) in meson_rtc_get_data() argument
120 meson_rtc_sclk_pulse(rtc); in meson_rtc_get_data()
123 regmap_read(rtc->peripheral, RTC_ADDR1, &tmp); in meson_rtc_get_data()
130 static int meson_rtc_get_bus(struct meson_rtc *rtc) in meson_rtc_get_bus() argument
137 regmap_update_bits(rtc->peripheral, RTC_ADDR0, val, 0); in meson_rtc_get_bus()
141 if (!regmap_read_poll_timeout(rtc->peripheral, RTC_ADDR1, val, in meson_rtc_get_bus()
146 dev_warn(rtc->dev, "failed to get bus, resetting RTC\n"); in meson_rtc_get_bus()
148 ret = reset_control_reset(rtc->reset); in meson_rtc_get_bus()
153 dev_err(rtc->dev, "bus is not ready\n"); in meson_rtc_get_bus()
154 return -ETIMEDOUT; in meson_rtc_get_bus()
160 struct meson_rtc *rtc = context; in meson_rtc_serial_bus_reg_read() local
163 ret = meson_rtc_get_bus(rtc); in meson_rtc_serial_bus_reg_read()
167 regmap_update_bits(rtc->peripheral, RTC_ADDR0, RTC_ADDR0_LINE_SEN, in meson_rtc_serial_bus_reg_read()
169 meson_rtc_send_bits(rtc, reg, RTC_ADDR_BITS); in meson_rtc_serial_bus_reg_read()
170 meson_rtc_set_dir(rtc, 0); in meson_rtc_serial_bus_reg_read()
171 *data = meson_rtc_get_data(rtc); in meson_rtc_serial_bus_reg_read()
179 struct meson_rtc *rtc = context; in meson_rtc_serial_bus_reg_write() local
182 ret = meson_rtc_get_bus(rtc); in meson_rtc_serial_bus_reg_write()
186 regmap_update_bits(rtc->peripheral, RTC_ADDR0, RTC_ADDR0_LINE_SEN, in meson_rtc_serial_bus_reg_write()
188 meson_rtc_send_bits(rtc, data, RTC_DATA_BITS); in meson_rtc_serial_bus_reg_write()
189 meson_rtc_send_bits(rtc, reg, RTC_ADDR_BITS); in meson_rtc_serial_bus_reg_write()
190 meson_rtc_set_dir(rtc, 1); in meson_rtc_serial_bus_reg_write()
201 .name = "serial-registers",
209 static int meson_rtc_write_static(struct meson_rtc *rtc, u32 data) in meson_rtc_write_static() argument
213 regmap_write(rtc->peripheral, RTC_REG4, in meson_rtc_write_static()
218 regmap_update_bits(rtc->peripheral, RTC_ADDR0, in meson_rtc_write_static()
222 return regmap_read_poll_timeout(rtc->peripheral, RTC_REG4, tmp, in meson_rtc_write_static()
227 /* RTC interface layer functions */
231 struct meson_rtc *rtc = dev_get_drvdata(dev); in meson_rtc_gettime() local
235 ret = regmap_read(rtc->serial, RTC_COUNTER, &time); in meson_rtc_gettime()
244 struct meson_rtc *rtc = dev_get_drvdata(dev); in meson_rtc_settime() local
246 return regmap_write(rtc->serial, RTC_COUNTER, rtc_tm_to_time64(tm)); in meson_rtc_settime()
259 struct meson_rtc *rtc = context; in meson_rtc_regmem_read() local
265 return regmap_bulk_read(rtc->serial, read_offset, buf, read_size); in meson_rtc_regmem_read()
271 struct meson_rtc *rtc = context; in meson_rtc_regmem_write() local
277 return regmap_bulk_write(rtc->serial, write_offset, buf, write_size); in meson_rtc_regmem_write()
283 .name = "meson-rtc-regmem", in meson_rtc_probe()
291 struct device *dev = &pdev->dev; in meson_rtc_probe()
292 struct meson_rtc *rtc; in meson_rtc_probe() local
298 rtc = devm_kzalloc(dev, sizeof(struct meson_rtc), GFP_KERNEL); in meson_rtc_probe()
299 if (!rtc) in meson_rtc_probe()
300 return -ENOMEM; in meson_rtc_probe()
306 platform_set_drvdata(pdev, rtc); in meson_rtc_probe()
308 rtc->dev = dev; in meson_rtc_probe()
310 rtc_dev->ops = &meson_rtc_ops; in meson_rtc_probe()
311 rtc_dev->range_max = U32_MAX; in meson_rtc_probe()
317 rtc->peripheral = devm_regmap_init_mmio(dev, base, in meson_rtc_probe()
319 if (IS_ERR(rtc->peripheral)) { in meson_rtc_probe()
321 return PTR_ERR(rtc->peripheral); in meson_rtc_probe()
324 rtc->reset = devm_reset_control_get(dev, NULL); in meson_rtc_probe()
325 if (IS_ERR(rtc->reset)) { in meson_rtc_probe()
327 return PTR_ERR(rtc->reset); in meson_rtc_probe()
330 rtc->vdd = devm_regulator_get(dev, "vdd"); in meson_rtc_probe()
331 if (IS_ERR(rtc->vdd)) { in meson_rtc_probe()
332 dev_err(dev, "failed to get the vdd-supply\n"); in meson_rtc_probe()
333 return PTR_ERR(rtc->vdd); in meson_rtc_probe()
336 ret = regulator_enable(rtc->vdd); in meson_rtc_probe()
338 dev_err(dev, "failed to enable vdd-supply\n"); in meson_rtc_probe()
342 ret = meson_rtc_write_static(rtc, MESON_STATIC_DEFAULT); in meson_rtc_probe()
348 rtc->serial = devm_regmap_init(dev, &meson_rtc_serial_bus, rtc, in meson_rtc_probe()
350 if (IS_ERR(rtc->serial)) { in meson_rtc_probe()
352 ret = PTR_ERR(rtc->serial); in meson_rtc_probe()
357 * check if we can read RTC counter, if not then the RTC is probably in meson_rtc_probe()
360 ret = regmap_read(rtc->serial, RTC_COUNTER, &tm); in meson_rtc_probe()
362 dev_err(dev, "cannot read RTC counter, RTC not functional\n"); in meson_rtc_probe()
366 meson_rtc_nvmem_config.priv = rtc; in meson_rtc_probe()
378 regulator_disable(rtc->vdd); in meson_rtc_probe()
383 { .compatible = "amlogic,meson6-rtc", },
384 { .compatible = "amlogic,meson8-rtc", },
385 { .compatible = "amlogic,meson8b-rtc", },
386 { .compatible = "amlogic,meson8m2-rtc", },
394 .name = "meson-rtc",
400 MODULE_DESCRIPTION("Amlogic Meson RTC Driver");
404 MODULE_ALIAS("platform:meson-rtc");