Skip to content

Commit 262f72b

Browse files
bijudasalexandrebelloni
authored andcommitted
rtc: isl1208: Add isl1208_set_xtoscb()
As per the HW manual, set the XTOSCB bit as follows: If using an external clock signal, set the XTOSCB bit as 1 to disable the crystal oscillator. If using an external crystal, the XTOSCB bit needs to be set at 0 to enable the crystal oscillator. Add isl1208_set_xtoscb() to set XTOSCB bit based on the clock-names property. Fallback is enabling the internal crystal oscillator. While at it, introduce a variable "sr" for reading the status register in probe() as it is reused for writing and also remove the unnecessary blank line. Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> Link: https://lore.kernel.org/r/20230623140948.384762-10-biju.das.jz@bp.renesas.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
1 parent 5923fc7 commit 262f72b

1 file changed

Lines changed: 51 additions & 6 deletions

File tree

drivers/rtc/rtc-isl1208.c

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include <linux/bcd.h>
9+
#include <linux/clk.h>
910
#include <linux/i2c.h>
1011
#include <linux/module.h>
1112
#include <linux/of_device.h>
@@ -175,6 +176,20 @@ isl1208_i2c_validate_client(struct i2c_client *client)
175176
return 0;
176177
}
177178

179+
static int isl1208_set_xtoscb(struct i2c_client *client, int sr, int xtosb_val)
180+
{
181+
/* Do nothing if bit is already set to desired value */
182+
if ((sr & ISL1208_REG_SR_XTOSCB) == xtosb_val)
183+
return 0;
184+
185+
if (xtosb_val)
186+
sr |= ISL1208_REG_SR_XTOSCB;
187+
else
188+
sr &= ~ISL1208_REG_SR_XTOSCB;
189+
190+
return i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr);
191+
}
192+
178193
static int
179194
isl1208_i2c_get_sr(struct i2c_client *client)
180195
{
@@ -511,7 +526,6 @@ isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
511526
return 0;
512527
}
513528

514-
515529
static int
516530
isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm)
517531
{
@@ -805,12 +819,26 @@ static int isl1208_setup_irq(struct i2c_client *client, int irq)
805819
return rc;
806820
}
807821

822+
static int
823+
isl1208_clk_present(struct i2c_client *client, const char *name)
824+
{
825+
struct clk *clk;
826+
827+
clk = devm_clk_get_optional(&client->dev, name);
828+
if (IS_ERR(clk))
829+
return PTR_ERR(clk);
830+
831+
return !!clk;
832+
}
833+
808834
static int
809835
isl1208_probe(struct i2c_client *client)
810836
{
811-
int rc = 0;
812837
struct isl1208_state *isl1208;
813838
int evdet_irq = -1;
839+
int xtosb_val = 0;
840+
int rc = 0;
841+
int sr;
814842

815843
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
816844
return -ENODEV;
@@ -837,6 +865,19 @@ isl1208_probe(struct i2c_client *client)
837865
isl1208->config = (struct isl1208_config *)id->driver_data;
838866
}
839867

868+
rc = isl1208_clk_present(client, "xin");
869+
if (rc < 0)
870+
return rc;
871+
872+
if (!rc) {
873+
rc = isl1208_clk_present(client, "clkin");
874+
if (rc < 0)
875+
return rc;
876+
877+
if (rc)
878+
xtosb_val = 1;
879+
}
880+
840881
isl1208->rtc = devm_rtc_allocate_device(&client->dev);
841882
if (IS_ERR(isl1208->rtc))
842883
return PTR_ERR(isl1208->rtc);
@@ -848,13 +889,17 @@ isl1208_probe(struct i2c_client *client)
848889
isl1208->nvmem_config.size = isl1208->config->nvmem_length;
849890
isl1208->nvmem_config.priv = isl1208;
850891

851-
rc = isl1208_i2c_get_sr(client);
852-
if (rc < 0) {
892+
sr = isl1208_i2c_get_sr(client);
893+
if (sr < 0) {
853894
dev_err(&client->dev, "reading status failed\n");
854-
return rc;
895+
return sr;
855896
}
856897

857-
if (rc & ISL1208_REG_SR_RTCF)
898+
rc = isl1208_set_xtoscb(client, sr, xtosb_val);
899+
if (rc)
900+
return rc;
901+
902+
if (sr & ISL1208_REG_SR_RTCF)
858903
dev_warn(&client->dev, "rtc power failure detected, "
859904
"please set clock.\n");
860905

0 commit comments

Comments
 (0)