S805 RTC driver
This has been sitting in my tree for a while, so I thought it would be a good idea to try and get it moving along and possibly submittied soon.
I've not been able to fully test this as I don't have an S805 MMC driver to allow me to boot to a userland on my ODroid-C1 board.
RFC 1/4 rtc: support for amlogic meson rtc
Add support for the AMLogic meson8b/meson6 RTC block.
--- drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-meson.c | 339 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 350 insertions(+) create mode 100644 drivers/rtc/rtc-meson.c
drivers/rtc/Kconfig +10 -0
@@ -1222,6 +1222,16 @@ config RTC_DRV_IMXDI This driver can also be built as a module, if so, the module will be called "rtc-imxdi". +config RTC_DRV_MESON + tristate "AMLogic Meson Real Time Clock" + depends on ARCH_MESON + help + Support for AMLogic Meson RTC block + + This driver can also be built as a module, if so, the module + will be called "rtc-meson". + + config RTC_DRV_OMAP tristate "TI OMAP Real Time Clock" depends on ARCH_OMAP || ARCH_DAVINCI || COMPILE_TEST
drivers/rtc/Makefile +1 -0
@@ -93,6 +93,7 @@ obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o +obj-$(CONFIG_RTC_DRV_MESON) += rtc-meson.o obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o
drivers/rtc/rtc-meson.c new file +339 -0
339 lines not on this page · raw message
Signature · 1 line
2.8.1
RFC 1/4 rtc: support for amlogic meson rtc
Hi Ben,
Quoted 4 lines · Ben Dooks
Add support for the AMLogic meson8b/meson6 RTC block.
Signed-off-by Ben Dooks <[email protected]>---
[...]
Quoted 12 lines
drivers/rtc/rtc-meson.c new file +12
-0+ +/* registers accessed from cpu bus */ +#define RTC_REG (x) ((x) * 4)/* rtc registers 0-4 */ + +#define LINE_SDI (1 << 2) +#define LINE_SEN (1 << 1) +#define LINE_SCLK (1 << 0) + +#define RTCREG0_START_SER BIT(17) +#define RTCREG0_WAIT_SER BIT(22) + +#define RTCREG1_READY BIT(1)
drivers/rtc/rtc-meson.c line 41
Quoted 10 lines
drivers/rtc/rtc-meson.c new file +10
-0+ +/* rtc registers accessed via rtc-serial inteface */ +#define RTC_COUNTER (0) +#define RTC_SEC_ADJ (2) + +#define RTC_ADDR_BITS (3)/* number of address bits to send */ +#define RTC_DATA_BITS (32)/* number of data bits to tx/rx */ + +#define MESON_STATIC_BIAS_CUR (0x5 << 1) +#define MESON_STATIC_VOLTAGE (0x3 << 11)
Cleanup indentation here.
Quoted 23 lines
drivers/rtc/rtc-meson.c new file +23
-0+ +struct meson_rtc { +struct rtc_device *rtc;/* rtc device we created */ +struct device *dev;/* device we bound from */ +struct reset_control *reset;/* reset source */ +struct mutex lock;/* rtc lock */ +void __iomem *regs;/* rtc register access */ +}; + +static void meson_rtc_setline (struct meson_rtc *rtc,unsigned bit,unsigned to) +{ +u32 reg0; + + reg0 =readl (rtc->regs +RTC_REG (0 )); +if (to) + reg0 |= bit; +else + reg0 &= ~bit; +writel (reg0, rtc->regs +RTC_REG (0 )); + +} + +static void meson_rtc_sclk_pulse (struct meson_rtc *rtc)
drivers/rtc/rtc-meson.c line 74
Quoted 10 lines
drivers/rtc/rtc-meson.c new file +10
-0+{ +udelay (5 ); +meson_rtc_setline (rtc,LINE_SCLK ,0 ); +udelay (5 ); +meson_rtc_setline (rtc,LINE_SCLK ,1 ); +} + +static void meson_rtc_send_bit (struct meson_rtc *rtc,unsigned bit) +{ +meson_rtc_setline (rtc,LINE_SDI , bit ?1 :0 );
You can use !!bit here also
Quoted 13 lines
drivers/rtc/rtc-meson.c new file +13
-0+meson_rtc_sclk_pulse (rtc); +} + +static void meson_rtc_send_bits (struct meson_rtc *rtc,u32 data,unsigned nr) +{ +u32 bit =1 << (nr -1 ); + +while (bit) { +meson_rtc_send_bit (rtc, data & bit); + bit >>=1 ; + } +} +
drivers/rtc/rtc-meson.c line 97
Quoted 10 lines
drivers/rtc/rtc-meson.c new file +10
-0+static void meson_rtc_set_dir (struct meson_rtc *rtc,u32 mode) +{ +meson_rtc_setline (rtc,LINE_SDI ,0 ); +meson_rtc_send_bit (rtc, mode); +meson_rtc_setline (rtc,LINE_SDI ,0 ); +} + +static u32 meson_rtc_read_sdo (struct meson_rtc *rtc) +{ +return readl (rtc->regs +RTC_REG (1 )) & (1 <<0 );
Drop the << 0 here, or replace by BIT(0)
Quoted 34 lines
drivers/rtc/rtc-meson.c new file +34
-0+} + +static u32 meson_rtc_get_data (struct meson_rtc *rtc) +{ +u32 val =0 ; +int bit; + +for (bit =0 ; bit <RTC_DATA_BITS ; bit++) { +meson_rtc_sclk_pulse (rtc); + val <<=1 ; + val |=meson_rtc_read_sdo (rtc); + } + +return val; +} + +static int meson_rtc_wait_bus (struct meson_rtc *rtc,unsigned timeout_ms) +{ +unsigned long timeout = jiffies +msecs_to_jiffies (timeout_ms); +u32 val; + + val =readl (rtc->regs +RTC_REG (0 )); + val &= ~(LINE_SDI |LINE_SEN |LINE_SCLK ); +writel (val, rtc->regs +RTC_REG (0 )); + +while (time_before (jiffies, timeout)) { + val =readl (rtc->regs +RTC_REG (1 )); +if (val &RTCREG1_READY ) +return 1 ; + +dev_info (rtc->dev,"%s: reg1=%08x\n" , __func__, val); +msleep (10 ); + } +
drivers/rtc/rtc-meson.c line 141
Quoted 10 lines
drivers/rtc/rtc-meson.c new file +10
-0+return 0 ; +} + +static int meson_rtc_get_bus (struct meson_rtc *rtc) +{ +int ret, retries =3 ; + +while (retries) { +if (meson_rtc_wait_bus (rtc,300 )) +return 0 ;
Put the timeout time in a define 300 to be easily changed.
Quoted 51 lines
drivers/rtc/rtc-meson.c new file +51
-0+ +dev_warn (rtc->dev,"failed to get bus, re-setting\n" ); + + retries--; + ret =reset_control_reset (rtc->reset); +if (ret) +return ret; + } + +dev_err (rtc->dev,"%s: bus is not ready\n" , __func__); +return -ETIMEDOUT ; +} + +static int meson_rtc_read (struct meson_rtc *rtc,unsigned int reg,u32 *data) +{ +int ret; + + ret =meson_rtc_get_bus (rtc); +if (ret) +return ret; + +meson_rtc_setline (rtc,LINE_SEN ,1 ); +meson_rtc_send_bits (rtc, reg,RTC_ADDR_BITS ); +meson_rtc_setline (rtc,LINE_SEN ,0 ); +meson_rtc_set_dir (rtc,0 ); + *data =meson_rtc_get_data (rtc); + +return 0 ; +} + +static int meson_rtc_write (struct meson_rtc *rtc,unsigned int reg,u32 data) +{ +int ret; + + ret =meson_rtc_get_bus (rtc); +if (ret) +return ret; + +meson_rtc_setline (rtc,LINE_SEN ,1 ); +meson_rtc_send_bits (rtc, reg,RTC_ADDR_BITS ); +meson_rtc_setline (rtc,LINE_SEN ,0 ); +meson_rtc_set_dir (rtc,1 ); +meson_rtc_send_bits (rtc, data,RTC_DATA_BITS ); + +return 0 ; +} + +static int meson_rtc_gettime (struct device *dev,struct rtc_time *tm) +{ +struct meson_rtc *rtc =dev_get_drvdata (dev); +int ret;
drivers/rtc/rtc-meson.c line 202
Quoted 10 lines
drivers/rtc/rtc-meson.c new file +10
-0+u32 time; + +mutex_lock (&rtc->lock); + + ret =meson_rtc_read (rtc,RTC_COUNTER , &time); +if (ret) +return ret; + +rtc_time_to_tm (time, tm); +dev_info (dev,"read time %lu\n" , (unsigned long )time);
Replace by a dev_dbg here.
Quoted 40 lines
drivers/rtc/rtc-meson.c new file +40
-0+ +mutex_unlock (&rtc->lock); +return 0 ; +} + +static int meson_rtc_settime (struct device *dev,struct rtc_time *tm) +{ +struct meson_rtc *rtc =dev_get_drvdata (dev); +unsigned long time; +int ret; + +mutex_lock (&rtc->lock); + +rtc_tm_to_time (tm, &time); + ret =meson_rtc_write (rtc,RTC_COUNTER , time); + +mutex_unlock (&rtc->lock); +return ret; +} + +static const struct rtc_class_ops meson_rtc_ops = { + .read_time = meson_rtc_gettime, + .set_time = meson_rtc_settime, +}; + +static int meson_rtc_wait_serialiser (struct meson_rtc *rtc) +{ +unsigned long timeout = jiffies +msecs_to_jiffies (100 ); + +while (time_before (jiffies, timeout)) { +if (!(readl (rtc->regs +RTC_REG (0 )) &RTCREG0_WAIT_SER )) +return 0 ; +msleep (10 ); + } + +return -ETIMEDOUT ; +} + +static int meson_rtc_write_static (struct meson_rtc *rtc,u32 data) +{
drivers/rtc/rtc-meson.c line 252
Quoted 10 lines
drivers/rtc/rtc-meson.c new file +10
-0+u32 tmp; + +mutex_lock (&rtc->lock); + +writel (data >>8 , rtc->regs +RTC_REG (4 )); + + tmp =readl (rtc->regs +RTC_REG (0 )); + tmp &= ~(0xff <<24 ); + tmp |= (data <<24 ); + tmp |=RTCREG0_START_SER ;
Add a define for the shifts here.
drivers/rtc/rtc-meson.c line 261
Quoted 9 lines
drivers/rtc/rtc-meson.c new file +9
-0+ +writel (tmp, rtc->regs +RTC_REG (0 )); + +if (meson_rtc_wait_serialiser (rtc)) +return -ETIMEDOUT ; + +dev_info (rtc->dev,"rtc_reg0 = %08x\n" ,readl (rtc->regs +RTC_REG (0 ))); +mutex_unlock (&rtc->lock); +
dev_dbg instead here.
Quoted 69 lines
drivers/rtc/rtc-meson.c new file +68
-0+return 0 ; +} + +static int meson_rtc_probe (struct platform_device *pdev) +{ +struct meson_rtc *rtc; +struct device *dev = &pdev->dev; +struct resource *res; +u32 tm; +int ret; + + rtc =devm_kzalloc (dev,sizeof (struct meson_rtc ),GFP_KERNEL ); +if (!rtc) { +dev_err (dev,"failed to allocate memory\n" ); +return -ENOMEM ; + } + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + rtc->regs =devm_ioremap_resource (dev, res); + rtc->dev = dev; + +if (IS_ERR (rtc->regs)) +return PTR_ERR (rtc->regs); + +mutex_init (&rtc->lock); +platform_set_drvdata (pdev, rtc); + + ret =meson_rtc_write_static (rtc, +MESON_STATIC_BIAS_CUR |MESON_STATIC_VOLTAGE ); +if (ret) { +dev_err (dev,"failed to set static values\n" ); +return ret; + } + + rtc->reset =devm_reset_control_get (dev,NULL ); +if (IS_ERR (rtc->reset)) +dev_warn (dev,"no reset available, rtc may not work\n" ); + +/* check if we can read RTC counter, if not then the RTC is probably +* not functional. If it isn't probably best to not bind */ + ret =meson_rtc_read (rtc,RTC_COUNTER , &tm); +if (ret) { +dev_err (dev,"cannot read RTC counter, RTC not functional\n" ); +return ret; + } + + rtc->rtc =devm_rtc_device_register (dev,"meson" , + &meson_rtc_ops,THIS_MODULE ); +if (IS_ERR (rtc->rtc)) { +dev_err (dev,"cannot attach rtc\n" ); +return PTR_ERR (rtc->rtc); + } + +dev_info (dev,"device registered\n" ); +return 0 ; +} + +static const struct of_device_id meson_rtc_dt_match[] = { + { .compatible ="amlogic,meson6-rtc" , }, + { .compatible ="amlogic,meson8-rtc" , }, + { .compatible ="amlogic,meson8b-rtc" , }, + { }, +}; +MODULE_DEVICE_TABLE (of, meson_rtc_dt_match); + +static struct platform_driver meson_rtc_driver = { + .probe = meson_rtc_probe, + .driver = {
drivers/rtc/rtc-meson.c line 339
Quoted 10 lines
drivers/rtc/rtc-meson.c new file +10
-0+ .name = "meson-rtc", + .of_match_table = of_match_ptr(meson_rtc_dt_match), + }, +}; +module_platform_driver (meson_rtc_driver); + +MODULE_DESCRIPTION ("AMLogic MESON RTC Driver" ); +MODULE_AUTHOR ("Ben Dooks <[email protected]>" ); +MODULE_LICENSE ("GPL" ); +MODULE_ALIAS ("platform:meson-rtc" );
Neil
RFC 1/4 rtc: support for amlogic meson rtc
Quoted 26 lines · Neil Armstrong
Hi Ben,
Quoted 4 lines · Ben Dooks
Add support for the AMLogic meson8b/meson6 RTC block.
Signed-off-by Ben Dooks <[email protected]>---
[...]
Quoted 16 lines
drivers/rtc/rtc-meson.c new file +16
-0+ +/* registers accessed from cpu bus */ +#define RTC_REG (x) ((x) * 4)/* rtc registers 0-4 */ + +#define LINE_SDI (1 << 2) +#define LINE_SEN (1 << 1) +#define LINE_SCLK (1 << 0) + +#define RTCREG0_START_SER BIT(17) +#define RTCREG0_WAIT_SER BIT(22) + +#define RTCREG1_READY BIT(1) + +/* rtc registers accessed via rtc-serial inteface */ +#define RTC_COUNTER (0) +#define RTC_SEC_ADJ (2)
Quoted 8 lines
drivers/rtc/rtc-meson.c line 41
Quoted 6 lines
drivers/rtc/rtc-meson.c new file +6
-0+ +#define RTC_ADDR_BITS (3)/* number of address bits to send */ +#define RTC_DATA_BITS (32)/* number of data bits to tx/rx */ + +#define MESON_STATIC_BIAS_CUR (0x5 << 1) +#define MESON_STATIC_VOLTAGE (0x3 << 11)Cleanup indentation here.
ok, will do.
Quoted 27 lines
Quoted 27 lines
drivers/rtc/rtc-meson.c new file +27
-0+ +struct meson_rtc { +struct rtc_device *rtc;/* rtc device we created */ +struct device *dev;/* device we bound from */ +struct reset_control *reset;/* reset source */ +struct mutex lock;/* rtc lock */ +void __iomem *regs;/* rtc register access */ +}; + +static void meson_rtc_setline (struct meson_rtc *rtc,unsigned bit,unsigned to) +{ +u32 reg0; + + reg0 =readl (rtc->regs +RTC_REG (0 )); +if (to) + reg0 |= bit; +else + reg0 &= ~bit; +writel (reg0, rtc->regs +RTC_REG (0 )); + +} + +static void meson_rtc_sclk_pulse (struct meson_rtc *rtc) +{ +udelay (5 ); +meson_rtc_setline (rtc,LINE_SCLK ,0 ); +udelay (5 );
Quoted 8 lines
drivers/rtc/rtc-meson.c line 74
Quoted 6 lines
drivers/rtc/rtc-meson.c new file +6
-0+meson_rtc_setline (rtc,LINE_SCLK ,1 ); +} + +static void meson_rtc_send_bit (struct meson_rtc *rtc,unsigned bit) +{ +meson_rtc_setline (rtc,LINE_SDI , bit ?1 :0 );You can use !!bit here also
I /could/ but I don't like it, and it's not going to improve the code.
Quoted 17 lines
Quoted 17 lines
drivers/rtc/rtc-meson.c new file +17
-0+meson_rtc_sclk_pulse (rtc); +} + +static void meson_rtc_send_bits (struct meson_rtc *rtc,u32 data,unsigned nr) +{ +u32 bit =1 << (nr -1 ); + +while (bit) { +meson_rtc_send_bit (rtc, data & bit); + bit >>=1 ; + } +} + +static void meson_rtc_set_dir (struct meson_rtc *rtc,u32 mode) +{ +meson_rtc_setline (rtc,LINE_SDI ,0 ); +meson_rtc_send_bit (rtc, mode);
Quoted 8 lines
drivers/rtc/rtc-meson.c line 97
Quoted 6 lines
drivers/rtc/rtc-meson.c new file +6
-0+meson_rtc_setline (rtc,LINE_SDI ,0 ); +} + +static u32 meson_rtc_read_sdo (struct meson_rtc *rtc) +{ +return readl (rtc->regs +RTC_REG (1 )) & (1 <<0 );Drop the << 0 here, or replace by BIT(0)
ok, will do.
Quoted 38 lines
Quoted 38 lines
drivers/rtc/rtc-meson.c new file +38
-0+} + +static u32 meson_rtc_get_data (struct meson_rtc *rtc) +{ +u32 val =0 ; +int bit; + +for (bit =0 ; bit <RTC_DATA_BITS ; bit++) { +meson_rtc_sclk_pulse (rtc); + val <<=1 ; + val |=meson_rtc_read_sdo (rtc); + } + +return val; +} + +static int meson_rtc_wait_bus (struct meson_rtc *rtc,unsigned timeout_ms) +{ +unsigned long timeout = jiffies +msecs_to_jiffies (timeout_ms); +u32 val; + + val =readl (rtc->regs +RTC_REG (0 )); + val &= ~(LINE_SDI |LINE_SEN |LINE_SCLK ); +writel (val, rtc->regs +RTC_REG (0 )); + +while (time_before (jiffies, timeout)) { + val =readl (rtc->regs +RTC_REG (1 )); +if (val &RTCREG1_READY ) +return 1 ; + +dev_info (rtc->dev,"%s: reg1=%08x\n" , __func__, val); +msleep (10 ); + } + +return 0 ; +} + +static int meson_rtc_get_bus (struct meson_rtc *rtc)
Quoted 8 lines
drivers/rtc/rtc-meson.c line 141
Quoted 6 lines
drivers/rtc/rtc-meson.c new file +6
-0+{ +int ret, retries =3 ; + +while (retries) { +if (meson_rtc_wait_bus (rtc,300 )) +return 0 ;Put the timeout time in a define 300 to be easily changed.
not sure that's necessary, it's just in one place.
Quoted 55 lines
Quoted 55 lines
drivers/rtc/rtc-meson.c new file +55
-0+ +dev_warn (rtc->dev,"failed to get bus, re-setting\n" ); + + retries--; + ret =reset_control_reset (rtc->reset); +if (ret) +return ret; + } + +dev_err (rtc->dev,"%s: bus is not ready\n" , __func__); +return -ETIMEDOUT ; +} + +static int meson_rtc_read (struct meson_rtc *rtc,unsigned int reg,u32 *data) +{ +int ret; + + ret =meson_rtc_get_bus (rtc); +if (ret) +return ret; + +meson_rtc_setline (rtc,LINE_SEN ,1 ); +meson_rtc_send_bits (rtc, reg,RTC_ADDR_BITS ); +meson_rtc_setline (rtc,LINE_SEN ,0 ); +meson_rtc_set_dir (rtc,0 ); + *data =meson_rtc_get_data (rtc); + +return 0 ; +} + +static int meson_rtc_write (struct meson_rtc *rtc,unsigned int reg,u32 data) +{ +int ret; + + ret =meson_rtc_get_bus (rtc); +if (ret) +return ret; + +meson_rtc_setline (rtc,LINE_SEN ,1 ); +meson_rtc_send_bits (rtc, reg,RTC_ADDR_BITS ); +meson_rtc_setline (rtc,LINE_SEN ,0 ); +meson_rtc_set_dir (rtc,1 ); +meson_rtc_send_bits (rtc, data,RTC_DATA_BITS ); + +return 0 ; +} + +static int meson_rtc_gettime (struct device *dev,struct rtc_time *tm) +{ +struct meson_rtc *rtc =dev_get_drvdata (dev); +int ret; +u32 time; + +mutex_lock (&rtc->lock); +
Quoted 8 lines
drivers/rtc/rtc-meson.c line 202
Quoted 6 lines
drivers/rtc/rtc-meson.c new file +6
-0+ ret =meson_rtc_read (rtc,RTC_COUNTER , &time); +if (ret) +return ret; + +rtc_time_to_tm (time, tm); +dev_info (dev,"read time %lu\n" , (unsigned long )time);Replace by a
dev_dbghere.
Already done for v2.
Quoted 53 lines
Quoted 40 lines
drivers/rtc/rtc-meson.c new file +40
-0+ +mutex_unlock (&rtc->lock); +return 0 ; +} + +static int meson_rtc_settime (struct device *dev,struct rtc_time *tm) +{ +struct meson_rtc *rtc =dev_get_drvdata (dev); +unsigned long time; +int ret; + +mutex_lock (&rtc->lock); + +rtc_tm_to_time (tm, &time); + ret =meson_rtc_write (rtc,RTC_COUNTER , time); + +mutex_unlock (&rtc->lock); +return ret; +} + +static const struct rtc_class_ops meson_rtc_ops = { + .read_time = meson_rtc_gettime, + .set_time = meson_rtc_settime, +}; + +static int meson_rtc_wait_serialiser (struct meson_rtc *rtc) +{ +unsigned long timeout = jiffies +msecs_to_jiffies (100 ); + +while (time_before (jiffies, timeout)) { +if (!(readl (rtc->regs +RTC_REG (0 )) &RTCREG0_WAIT_SER )) +return 0 ; +msleep (10 ); + } + +return -ETIMEDOUT ; +} + +static int meson_rtc_write_static (struct meson_rtc *rtc,u32 data) +{drivers/rtc/rtc-meson.c line 252
Quoted 10 lines
drivers/rtc/rtc-meson.c new file +10
-0+u32 tmp; + +mutex_lock (&rtc->lock); + +writel (data >>8 , rtc->regs +RTC_REG (4 )); + + tmp =readl (rtc->regs +RTC_REG (0 )); + tmp &= ~(0xff <<24 ); + tmp |= (data <<24 ); + tmp |=RTCREG0_START_SER ;Add a define for the shifts here.
Quoted 11 lines
drivers/rtc/rtc-meson.c line 261
Quoted 9 lines
drivers/rtc/rtc-meson.c new file +9
-0+ +writel (tmp, rtc->regs +RTC_REG (0 )); + +if (meson_rtc_wait_serialiser (rtc)) +return -ETIMEDOUT ; + +dev_info (rtc->dev,"rtc_reg0 = %08x\n" ,readl (rtc->regs +RTC_REG (0 ))); +mutex_unlock (&rtc->lock); +
dev_dbginstead here.
Yep, caught already for v2.
Quoted 74 lines
Quoted 74 lines
drivers/rtc/rtc-meson.c new file +74
-0+return 0 ; +} + +static int meson_rtc_probe (struct platform_device *pdev) +{ +struct meson_rtc *rtc; +struct device *dev = &pdev->dev; +struct resource *res; +u32 tm; +int ret; + + rtc =devm_kzalloc (dev,sizeof (struct meson_rtc ),GFP_KERNEL ); +if (!rtc) { +dev_err (dev,"failed to allocate memory\n" ); +return -ENOMEM ; + } + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + rtc->regs =devm_ioremap_resource (dev, res); + rtc->dev = dev; + +if (IS_ERR (rtc->regs)) +return PTR_ERR (rtc->regs); + +mutex_init (&rtc->lock); +platform_set_drvdata (pdev, rtc); + + ret =meson_rtc_write_static (rtc, +MESON_STATIC_BIAS_CUR |MESON_STATIC_VOLTAGE ); +if (ret) { +dev_err (dev,"failed to set static values\n" ); +return ret; + } + + rtc->reset =devm_reset_control_get (dev,NULL ); +if (IS_ERR (rtc->reset)) +dev_warn (dev,"no reset available, rtc may not work\n" ); + +/* check if we can read RTC counter, if not then the RTC is probably +* not functional. If it isn't probably best to not bind */ + ret =meson_rtc_read (rtc,RTC_COUNTER , &tm); +if (ret) { +dev_err (dev,"cannot read RTC counter, RTC not functional\n" ); +return ret; + } + + rtc->rtc =devm_rtc_device_register (dev,"meson" , + &meson_rtc_ops,THIS_MODULE ); +if (IS_ERR (rtc->rtc)) { +dev_err (dev,"cannot attach rtc\n" ); +return PTR_ERR (rtc->rtc); + } + +dev_info (dev,"device registered\n" ); +return 0 ; +} + +static const struct of_device_id meson_rtc_dt_match[] = { + { .compatible ="amlogic,meson6-rtc" , }, + { .compatible ="amlogic,meson8-rtc" , }, + { .compatible ="amlogic,meson8b-rtc" , }, + { }, +}; +MODULE_DEVICE_TABLE (of, meson_rtc_dt_match); + +static struct platform_driver meson_rtc_driver = { + .probe = meson_rtc_probe, + .driver = { + .name ="meson-rtc" , + .of_match_table =of_match_ptr (meson_rtc_dt_match), + }, +}; +module_platform_driver (meson_rtc_driver); +
Quoted 8 lines
drivers/rtc/rtc-meson.c line 339
Quoted 5 lines
drivers/rtc/rtc-meson.c new file +4
-0+MODULE_DESCRIPTION ("AMLogic MESON RTC Driver" ); +MODULE_AUTHOR ("Ben Dooks <[email protected]>" ); +MODULE_LICENSE ("GPL" ); +MODULE_ALIAS ("platform:meson-rtc" );Neil
Ta.
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius
RFC 1/4 rtc: support for amlogic meson rtc
In reply to Ben DooksQuoted 15 lines · Ben Dooks
Add support for the AMLogic meson8b/meson6 RTC block.
Signed-off-by Ben Dooks <[email protected]>--- drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-meson.c | 339 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 350 insertions(+) create mode 100644 drivers/rtc/rtc-meson.cdrivers/rtc/Kconfig +0
-0
drivers/rtc/Kconfig config RTC_DRV_IMXDI · line 1227
Quoted 6 lines
drivers/rtc/Kconfig +3
-0@@ -1222,6 +1222,16 @@ config RTC_DRV_IMXDI This driver can also be built as a module, if so, the module will be called "rtc-imxdi". +config RTC_DRV_MESON + tristate "AMLogic Meson Real Time Clock" + depends on ARCH_MESON
You can also || COMPILE_TEST here
drivers/rtc/Kconfig config RTC_DRV_IMXDI · line 1237
Quoted 10 lines
drivers/rtc/Kconfig +7
-0+ help + Support for AMLogic Meson RTC block + + This driver can also be built as a module, if so, the module + will be called "rtc-meson". + + config RTC_DRV_OMAP tristate "TI OMAP Real Time Clock" depends on ARCH_OMAP || ARCH_DAVINCI || COMPILE_TEST
Neil
RFC 2/4 odroidc1: enable rtc
In reply to Ben Dooks--- arch/arm/boot/dts/meson8b-odroidc1.dts | 5 +++++ 1 file changed, 5 insertions(+)
arch/arm/boot/dts/meson8b-odroidc1.dts +5 -0
@@ -76,3 +76,8 @@ pinctrl-0 = <&uart_ao_a_pins>; pinctrl-names = "default"; }; + +&rtc { + status = "okay"; +}; +
Signature · 1 line
2.8.1
RFC 3/4 meson-rtc: add device-tree binding
In reply to Ben Dooks--- .../devicetree/bindings/rtc/rtc-amlogic.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Documentation/devicetree/bindings/rtc/rtc-amlogic.txt
Documentation/devicetree/bindings/rtc/rtc-amlogic.txt new file +21 -0
@@ -0,0 +1,21 @@ +* AMlogic Meson RTC + +Required properties: +- compatible: should be one of the following describing the hardware: + * "amlogic,meson6-rtc" + * "amlogic,meson8-rtc" + * "amlogic,meson8b-rtc" + +- reg: physical register space for the controller's memory mapped registers. + +Optional properties: +- resets: reset controller reference to allow reset of the controller +- interrupts: single interrupt reference if interrupt support needed + +Example: + + rtc: rtc at c8100740 { + compatible = "amlogic,meson6-rtc"; + reg = <0xc8100740 0x14>; + status = "disabled"; + };
Signature · 1 line
2.8.1
RFC 4/4 meson8b: add rtc node
In reply to Ben Dooks--- arch/arm/boot/dts/meson8b.dtsi | 7 +++++++ 1 file changed, 7 insertions(+)
arch/arm/boot/dts/meson8b.dtsi +7 -0
@@ -156,6 +156,13 @@ status = "disabled"; }; + rtc: rtc at c8100740 { + compatible = "amlogic,meson8b-rtc"; + reg = <0xc8100740 0x14>; + resets = <&reset RESET_RTC>; + status = "disabled"; + }; + clkc: clock-controller at c1104000 { #clock-cells = <1>; compatible = "amlogic,meson8b-clkc";
Signature · 1 line
2.8.1
Quoted 7 lines · Ben Dooks
This has been sitting in my tree for a while, so I thought it would be a good idea to try and get it moving along and possibly submittied soon.
I've not been able to fully test this as I don't have an S805 MMC driver to allow me to boot to a userland on my ODroid-C1 board.
If no-one is going to comment, I will submit this on Monday.
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius
Quoted 7 lines · Ben Dooks
This has been sitting in my tree for a while, so I thought it would be a good idea to try and get it moving along and possibly submittied soon.
I've not been able to fully test this as I don't have an S805 MMC driver to allow me to boot to a userland on my ODroid-C1 board.
You could generate a dummy buildroot initramfs loaded in the Image with the RTC tools.
Neil
Quoted 6 lines
_______________________________________________
linux-amlogic mailing list
linux-amlogic at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic
Quoted 10 lines · Neil Armstrong
Quoted 7 lines · Ben Dooks
This has been sitting in my tree for a while, so I thought it would be a good idea to try and get it moving along and possibly submittied soon.
I've not been able to fully test this as I don't have an S805 MMC driver to allow me to boot to a userland on my ODroid-C1 board.
You could generate a dummy buildroot initramfs loaded in the Image with the RTC tools.
I managed to get the older 4.x mmc driver from Carlo working so have a debian image to build.
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius
Quoted 10 lines · Neil Armstrong
Quoted 7 lines · Ben Dooks
This has been sitting in my tree for a while, so I thought it would be a good idea to try and get it moving along and possibly submittied soon.
I've not been able to fully test this as I don't have an S805 MMC driver to allow me to boot to a userland on my ODroid-C1 board.
You could generate a dummy buildroot initramfs loaded in the Image with the RTC tools.
Thanks for the review, will try and send a RFCv2 today.
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius