* [PATCH 0/1] rtc: ds1307: add support for clock provider in ds1307 @ 2025-08-19 10:46 Akhilesh Patil 2025-08-19 10:47 ` [PATCH 1/1] " Akhilesh Patil 0 siblings, 1 reply; 3+ messages in thread From: Akhilesh Patil @ 2025-08-19 10:46 UTC (permalink / raw) To: alexandre.belloni, mturquette, sboyd Cc: linux-rtc, linux-clk, linux-kernel, akhileshpatilvnit, skhan Hi all, This work adds support for square-wave output from ds1307 rtc chip. ds1307 rtc supports generating 4 rates of square wave output signal, 1, 4096, 8192, 32768 Hz. This output can be controlled by device register - CONTROL_REGISTER at I2C address 0x7 as follows: OUT [7] : control default state of SQW/OUT pin if clock output is disabled. SQWE [4] : Enable/Disable output clock RS [1:0] : Select the rate for output clock. Other devices can use this clock via DT and Common Clock Framework. I have done testing and validation using CCF's debugfs interface. Below are the details of test/validation done for this patch. *** Test setup Hardware: * I am using Texas Instruments AM62x SK board (ARM64 based SoC) * ds1307 RTC hardware module. * I have connected ds1307 module at I2C0 bus of am62x available at 40pin user expansion connector headers. SDA --> pin 27 SCL --> pin 28 No pull up needed as board already have pull ups on I2C0 lines. * 24MHz logic analyzer to see the waveforms and validate frequency. Kernel: * v6.17-rc2 * define CLOCK_ALLOW_WRITE_DEBUGFS manually in drivers/clk/clk.c so that we can use debugfs interface to test setting clock rates. Note: This config is intentionally kept manual in the kernel and should be defined manually only. *** Validation steps: Step 1: Probe the module $ modprobe rtc-ds1307 Step 2: Mount debugfs $ mount -t debugfs none /sys/kernel/debug Step 3: Instantiate device $ echo "ds1307 0x68" > /sys/class/i2c-dev/i2c-0/device/new_device Step 4: read initial rate $ cat /sys/kernel/debug/clk/ds1307_clk_sqw/clk_rate 1 Step 5: Set rate to 8192 and enable square-wave output $ echo 8192 > /sys/kernel/debug/clk/ds1307_clk_sqw/clk_rate $ echo 1 > /sys/kernel/debug/clk/ds1307_clk_sqw/clk_prepare_enable Step 6: Verify rate $ cat /sys/kernel/debug/clk/ds1307_clk_sqw/clk_rate 8192 Validate output clock using logic analyzer. Probe at pin #7 (SQW/OUT) of ds1307 chip. Step 7: delete the device $ echo "0x68" > /sys/class/i2c-dev/i2c-0/device/delete_device Step 8: use i2ctools to direct read device register 0x7 $ i2cget -y 0 0x68 0x7 0x12 0x12 shows that clock is enabled with frequency 8192Hz by our driver. step 9: Redo Step 3 through 8 for various supported rates I have put few important debug printk() on various callbacks to validate codepaths. Below is testing log for various random rates. $ echo 81929999 > /sys/kernel/debug/clk/ds1307_clk [ 913.107859] ds1307 determine rate callback rate: [ 913.114978] DS1307 set rate callback [ 913.119598] ds1307 recalc rate callback rate: 1 $ echo 10 > /sys/kernel/debug/clk/ds1307_clk [ 976.439016] ds1307 determine rate callback rate: [ 976.446192] DS1307 set rate callback [ 976.450849] ds1307 recalc rate callback rate: 4096 $ echo 5000 > /sys/kernel/debug/clk/ds1307_clk [ 991.732748] ds1307 determine rate callback rate: [ 991.739954] DS1307 set rate callback [ 991.744576] ds1307 recalc rate callback rate: 8192 $ echo 9000 > /sys/kernel/debug/clk/ds1307_clk [ 1007.463786] ds1307 determine rate callback rate: [ 1007.471000] DS1307 set rate callback [ 1007.475636] ds1307 recalc rate callback rate: 32768 $ echo 40000 > /sys/kernel/debug/clk/ds1307_clk [ 1020.292701] ds1307 determine rate callback rate: [ 1020.299934] DS1307 set rate callback [ 1020.304563] ds1307 recalc rate callback rate: 1 Regards, Akhilesh Akhilesh Patil (1): rtc: ds1307: add support for clock provider in ds1307 drivers/rtc/rtc-ds1307.c | 139 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 2 deletions(-) -- 2.34.1 ^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/1] rtc: ds1307: add support for clock provider in ds1307 2025-08-19 10:46 [PATCH 0/1] rtc: ds1307: add support for clock provider in ds1307 Akhilesh Patil @ 2025-08-19 10:47 ` Akhilesh Patil 2026-06-24 21:15 ` Alexandre Belloni 0 siblings, 1 reply; 3+ messages in thread From: Akhilesh Patil @ 2025-08-19 10:47 UTC (permalink / raw) To: alexandre.belloni, mturquette, sboyd Cc: linux-rtc, linux-clk, linux-kernel, akhileshpatilvnit, skhan Add support for square-wave output for ds1307 rtc via common clock framework clock provider. tested on TI am62x SK board using ds1307 RTC hardware module. Signed-off-by: Akhilesh Patil <akhilesh@ee.iitb.ac.in> --- drivers/rtc/rtc-ds1307.c | 139 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 7205c59ff729..dd99b9a3836d 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1658,18 +1658,153 @@ static int ds3231_clks_register(struct ds1307 *ds1307) return 0; } +/* ds1307 RTC clock output support */ +static unsigned long ds1307_clk_rates[] = { + 1, + 4096, + 8192, + 32768, +}; + +static unsigned long ds1307_clk_sqw_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + int ret; + unsigned int rate_id; + struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); + + ret = regmap_read(ds1307->regmap, DS1307_REG_CONTROL, &rate_id); + if (ret) + return ret; + + rate_id &= (DS1307_BIT_RS1 | DS1307_BIT_RS0); + + return ds1307_clk_rates[rate_id]; +} + +static int ds1307_clk_sqw_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ds1307_clk_rates); i++) { + if (req->rate <= ds1307_clk_rates[i]) { + req->rate = ds1307_clk_rates[i]; + return 0; + } + } + + /* Default rate 1Hz */ + req->rate = ds1307_clk_rates[0]; + + return 0; +} + +static int ds1307_clk_sqw_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + int id, ret; + struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); + + for (id = 0; id < ARRAY_SIZE(ds1307_clk_rates); id++) { + if (ds1307_clk_rates[id] == rate) + break; + } + + if (id >= ARRAY_SIZE(ds1307_clk_rates)) + return -EINVAL; + + ret = regmap_update_bits(ds1307->regmap, DS1307_REG_CONTROL, + DS1307_BIT_RS0 | DS1307_BIT_RS1, id); + + return ret; +} + +static int ds1307_clk_sqw_prepare(struct clk_hw *hw) +{ + int ret; + struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); + + ret = regmap_update_bits(ds1307->regmap, DS1307_REG_CONTROL, + DS1307_BIT_SQWE, DS1307_BIT_SQWE); + + return ret; +} + +static void ds1307_clk_sqw_unprepare(struct clk_hw *hw) +{ + struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); + + regmap_update_bits(ds1307->regmap, DS1307_REG_CONTROL, + DS1307_BIT_SQWE, ~DS1307_BIT_SQWE); +} + +static int ds1307_clk_sqw_is_prepared(struct clk_hw *hw) +{ + int ret; + struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); + unsigned int status; + + ret = regmap_read(ds1307->regmap, DS1307_REG_CONTROL, &status); + if (ret) + return ret; + + return !!(status & DS1307_BIT_SQWE); +} + +static const struct clk_ops ds1307_clk_sqw_ops = { + .prepare = ds1307_clk_sqw_prepare, + .unprepare = ds1307_clk_sqw_unprepare, + .is_prepared = ds1307_clk_sqw_is_prepared, + .recalc_rate = ds1307_clk_sqw_recalc_rate, + .set_rate = ds1307_clk_sqw_set_rate, + .determine_rate = ds1307_clk_sqw_determine_rate, +}; + +static int rtc_ds1307_clks_register(struct ds1307 *ds1307) +{ + struct device_node *node = ds1307->dev->of_node; + struct clk *clk; + struct clk_init_data init = {0}; + + init.name = "ds1307_clk_sqw"; + init.ops = &ds1307_clk_sqw_ops; + + ds1307->clks[0].init = &init; + + /* Register the clock with CCF */ + clk = devm_clk_register(ds1307->dev, &ds1307->clks[0]); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + if (node) + of_clk_add_provider(node, of_clk_src_simple_get, clk); + + return 0; +} + static void ds1307_clks_register(struct ds1307 *ds1307) { int ret; - if (ds1307->type != ds_3231) + switch (ds1307->type) { + case ds_3231: + ret = ds3231_clks_register(ds1307); + break; + + case ds_1307: + ret = rtc_ds1307_clks_register(ds1307); + break; + + default: return; + } - ret = ds3231_clks_register(ds1307); if (ret) { dev_warn(ds1307->dev, "unable to register clock device %d\n", ret); } + } #else -- 2.34.1 ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 1/1] rtc: ds1307: add support for clock provider in ds1307 2025-08-19 10:47 ` [PATCH 1/1] " Akhilesh Patil @ 2026-06-24 21:15 ` Alexandre Belloni 0 siblings, 0 replies; 3+ messages in thread From: Alexandre Belloni @ 2026-06-24 21:15 UTC (permalink / raw) To: mturquette, sboyd, Akhilesh Patil Cc: linux-rtc, linux-clk, linux-kernel, akhileshpatilvnit, skhan On Tue, 19 Aug 2025 16:17:23 +0530, Akhilesh Patil wrote: > Add support for square-wave output for ds1307 rtc via > common clock framework clock provider. > > tested on TI am62x SK board using ds1307 RTC hardware module. Applied, thanks! [1/1] rtc: ds1307: add support for clock provider in ds1307 https://git.kernel.org/abelloni/c/18d39c71e317 Best regards, -- Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-06-24 21:15 UTC | newest] Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-08-19 10:46 [PATCH 0/1] rtc: ds1307: add support for clock provider in ds1307 Akhilesh Patil 2025-08-19 10:47 ` [PATCH 1/1] " Akhilesh Patil 2026-06-24 21:15 ` Alexandre Belloni
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®