diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2016-01-31 09:10:10 -0500 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2016-03-14 12:08:13 -0400 |
commit | 6c6ff145b3346b071e7d80f9bd33aa7de0e438bc (patch) | |
tree | bdd4e8997f5b9c64ec1d00d219e0d18cd27999d8 /drivers/rtc | |
parent | f3937549a975fadec9b517b059616f08f9cb7653 (diff) |
rtc: ds1307: add clock provider support for DS3231
DS3231 has programmable square-wave output signal.
This enables to use this feature as a clock provider of
common clock framework.
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Reviewed-by: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 296 |
1 files changed, 295 insertions, 1 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 2462d5a53a53..b2156ee5bae1 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <linux/hwmon.h> | 22 | #include <linux/hwmon.h> |
23 | #include <linux/hwmon-sysfs.h> | 23 | #include <linux/hwmon-sysfs.h> |
24 | #include <linux/clk-provider.h> | ||
24 | 25 | ||
25 | /* | 26 | /* |
26 | * We can't determine type by probing, but if we expect pre-Linux code | 27 | * We can't determine type by probing, but if we expect pre-Linux code |
@@ -91,6 +92,7 @@ enum ds_type { | |||
91 | # define DS1340_BIT_OSF 0x80 | 92 | # define DS1340_BIT_OSF 0x80 |
92 | #define DS1337_REG_STATUS 0x0f | 93 | #define DS1337_REG_STATUS 0x0f |
93 | # define DS1337_BIT_OSF 0x80 | 94 | # define DS1337_BIT_OSF 0x80 |
95 | # define DS3231_BIT_EN32KHZ 0x08 | ||
94 | # define DS1337_BIT_A2I 0x02 | 96 | # define DS1337_BIT_A2I 0x02 |
95 | # define DS1337_BIT_A1I 0x01 | 97 | # define DS1337_BIT_A1I 0x01 |
96 | #define DS1339_REG_ALARM1_SECS 0x07 | 98 | #define DS1339_REG_ALARM1_SECS 0x07 |
@@ -120,6 +122,9 @@ struct ds1307 { | |||
120 | u8 length, u8 *values); | 122 | u8 length, u8 *values); |
121 | s32 (*write_block_data)(const struct i2c_client *client, u8 command, | 123 | s32 (*write_block_data)(const struct i2c_client *client, u8 command, |
122 | u8 length, const u8 *values); | 124 | u8 length, const u8 *values); |
125 | #ifdef CONFIG_COMMON_CLK | ||
126 | struct clk_hw clks[2]; | ||
127 | #endif | ||
123 | }; | 128 | }; |
124 | 129 | ||
125 | struct chip_desc { | 130 | struct chip_desc { |
@@ -926,7 +931,295 @@ static void ds1307_hwmon_register(struct ds1307 *ds1307) | |||
926 | { | 931 | { |
927 | } | 932 | } |
928 | 933 | ||
929 | #endif | 934 | #endif /* CONFIG_RTC_DRV_DS1307_HWMON */ |
935 | |||
936 | /*----------------------------------------------------------------------*/ | ||
937 | |||
938 | /* | ||
939 | * Square-wave output support for DS3231 | ||
940 | * Datasheet: https://datasheets.maximintegrated.com/en/ds/DS3231.pdf | ||
941 | */ | ||
942 | #ifdef CONFIG_COMMON_CLK | ||
943 | |||
944 | enum { | ||
945 | DS3231_CLK_SQW = 0, | ||
946 | DS3231_CLK_32KHZ, | ||
947 | }; | ||
948 | |||
949 | #define clk_sqw_to_ds1307(clk) \ | ||
950 | container_of(clk, struct ds1307, clks[DS3231_CLK_SQW]) | ||
951 | #define clk_32khz_to_ds1307(clk) \ | ||
952 | container_of(clk, struct ds1307, clks[DS3231_CLK_32KHZ]) | ||
953 | |||
954 | static int ds3231_clk_sqw_rates[] = { | ||
955 | 1, | ||
956 | 1024, | ||
957 | 4096, | ||
958 | 8192, | ||
959 | }; | ||
960 | |||
961 | static int ds1337_write_control(struct ds1307 *ds1307, u8 mask, u8 value) | ||
962 | { | ||
963 | struct i2c_client *client = ds1307->client; | ||
964 | struct mutex *lock = &ds1307->rtc->ops_lock; | ||
965 | int control; | ||
966 | int ret; | ||
967 | |||
968 | mutex_lock(lock); | ||
969 | |||
970 | control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); | ||
971 | if (control < 0) { | ||
972 | ret = control; | ||
973 | goto out; | ||
974 | } | ||
975 | |||
976 | control &= ~mask; | ||
977 | control |= value; | ||
978 | |||
979 | ret = i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, control); | ||
980 | out: | ||
981 | mutex_unlock(lock); | ||
982 | |||
983 | return ret; | ||
984 | } | ||
985 | |||
986 | static unsigned long ds3231_clk_sqw_recalc_rate(struct clk_hw *hw, | ||
987 | unsigned long parent_rate) | ||
988 | { | ||
989 | struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); | ||
990 | int control; | ||
991 | int rate_sel = 0; | ||
992 | |||
993 | control = i2c_smbus_read_byte_data(ds1307->client, DS1337_REG_CONTROL); | ||
994 | if (control < 0) | ||
995 | return control; | ||
996 | if (control & DS1337_BIT_RS1) | ||
997 | rate_sel += 1; | ||
998 | if (control & DS1337_BIT_RS2) | ||
999 | rate_sel += 2; | ||
1000 | |||
1001 | return ds3231_clk_sqw_rates[rate_sel]; | ||
1002 | } | ||
1003 | |||
1004 | static long ds3231_clk_sqw_round_rate(struct clk_hw *hw, unsigned long rate, | ||
1005 | unsigned long *prate) | ||
1006 | { | ||
1007 | int i; | ||
1008 | |||
1009 | for (i = ARRAY_SIZE(ds3231_clk_sqw_rates) - 1; i >= 0; i--) { | ||
1010 | if (ds3231_clk_sqw_rates[i] <= rate) | ||
1011 | return ds3231_clk_sqw_rates[i]; | ||
1012 | } | ||
1013 | |||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
1017 | static int ds3231_clk_sqw_set_rate(struct clk_hw *hw, unsigned long rate, | ||
1018 | unsigned long parent_rate) | ||
1019 | { | ||
1020 | struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); | ||
1021 | int control = 0; | ||
1022 | int rate_sel; | ||
1023 | |||
1024 | for (rate_sel = 0; rate_sel < ARRAY_SIZE(ds3231_clk_sqw_rates); | ||
1025 | rate_sel++) { | ||
1026 | if (ds3231_clk_sqw_rates[rate_sel] == rate) | ||
1027 | break; | ||
1028 | } | ||
1029 | |||
1030 | if (rate_sel == ARRAY_SIZE(ds3231_clk_sqw_rates)) | ||
1031 | return -EINVAL; | ||
1032 | |||
1033 | if (rate_sel & 1) | ||
1034 | control |= DS1337_BIT_RS1; | ||
1035 | if (rate_sel & 2) | ||
1036 | control |= DS1337_BIT_RS2; | ||
1037 | |||
1038 | return ds1337_write_control(ds1307, DS1337_BIT_RS1 | DS1337_BIT_RS2, | ||
1039 | control); | ||
1040 | } | ||
1041 | |||
1042 | static int ds3231_clk_sqw_prepare(struct clk_hw *hw) | ||
1043 | { | ||
1044 | struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); | ||
1045 | |||
1046 | return ds1337_write_control(ds1307, DS1337_BIT_INTCN, 0); | ||
1047 | } | ||
1048 | |||
1049 | static void ds3231_clk_sqw_unprepare(struct clk_hw *hw) | ||
1050 | { | ||
1051 | struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); | ||
1052 | |||
1053 | ds1337_write_control(ds1307, DS1337_BIT_INTCN, DS1337_BIT_INTCN); | ||
1054 | } | ||
1055 | |||
1056 | static int ds3231_clk_sqw_is_prepared(struct clk_hw *hw) | ||
1057 | { | ||
1058 | struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); | ||
1059 | int control; | ||
1060 | |||
1061 | control = i2c_smbus_read_byte_data(ds1307->client, DS1337_REG_CONTROL); | ||
1062 | if (control < 0) | ||
1063 | return control; | ||
1064 | |||
1065 | return !(control & DS1337_BIT_INTCN); | ||
1066 | } | ||
1067 | |||
1068 | static const struct clk_ops ds3231_clk_sqw_ops = { | ||
1069 | .prepare = ds3231_clk_sqw_prepare, | ||
1070 | .unprepare = ds3231_clk_sqw_unprepare, | ||
1071 | .is_prepared = ds3231_clk_sqw_is_prepared, | ||
1072 | .recalc_rate = ds3231_clk_sqw_recalc_rate, | ||
1073 | .round_rate = ds3231_clk_sqw_round_rate, | ||
1074 | .set_rate = ds3231_clk_sqw_set_rate, | ||
1075 | }; | ||
1076 | |||
1077 | static unsigned long ds3231_clk_32khz_recalc_rate(struct clk_hw *hw, | ||
1078 | unsigned long parent_rate) | ||
1079 | { | ||
1080 | return 32768; | ||
1081 | } | ||
1082 | |||
1083 | static int ds3231_clk_32khz_control(struct ds1307 *ds1307, bool enable) | ||
1084 | { | ||
1085 | struct i2c_client *client = ds1307->client; | ||
1086 | struct mutex *lock = &ds1307->rtc->ops_lock; | ||
1087 | int status; | ||
1088 | int ret; | ||
1089 | |||
1090 | mutex_lock(lock); | ||
1091 | |||
1092 | status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS); | ||
1093 | if (status < 0) { | ||
1094 | ret = status; | ||
1095 | goto out; | ||
1096 | } | ||
1097 | |||
1098 | if (enable) | ||
1099 | status |= DS3231_BIT_EN32KHZ; | ||
1100 | else | ||
1101 | status &= ~DS3231_BIT_EN32KHZ; | ||
1102 | |||
1103 | ret = i2c_smbus_write_byte_data(client, DS1337_REG_STATUS, status); | ||
1104 | out: | ||
1105 | mutex_unlock(lock); | ||
1106 | |||
1107 | return ret; | ||
1108 | } | ||
1109 | |||
1110 | static int ds3231_clk_32khz_prepare(struct clk_hw *hw) | ||
1111 | { | ||
1112 | struct ds1307 *ds1307 = clk_32khz_to_ds1307(hw); | ||
1113 | |||
1114 | return ds3231_clk_32khz_control(ds1307, true); | ||
1115 | } | ||
1116 | |||
1117 | static void ds3231_clk_32khz_unprepare(struct clk_hw *hw) | ||
1118 | { | ||
1119 | struct ds1307 *ds1307 = clk_32khz_to_ds1307(hw); | ||
1120 | |||
1121 | ds3231_clk_32khz_control(ds1307, false); | ||
1122 | } | ||
1123 | |||
1124 | static int ds3231_clk_32khz_is_prepared(struct clk_hw *hw) | ||
1125 | { | ||
1126 | struct ds1307 *ds1307 = clk_32khz_to_ds1307(hw); | ||
1127 | int status; | ||
1128 | |||
1129 | status = i2c_smbus_read_byte_data(ds1307->client, DS1337_REG_STATUS); | ||
1130 | if (status < 0) | ||
1131 | return status; | ||
1132 | |||
1133 | return !!(status & DS3231_BIT_EN32KHZ); | ||
1134 | } | ||
1135 | |||
1136 | static const struct clk_ops ds3231_clk_32khz_ops = { | ||
1137 | .prepare = ds3231_clk_32khz_prepare, | ||
1138 | .unprepare = ds3231_clk_32khz_unprepare, | ||
1139 | .is_prepared = ds3231_clk_32khz_is_prepared, | ||
1140 | .recalc_rate = ds3231_clk_32khz_recalc_rate, | ||
1141 | }; | ||
1142 | |||
1143 | static struct clk_init_data ds3231_clks_init[] = { | ||
1144 | [DS3231_CLK_SQW] = { | ||
1145 | .name = "ds3231_clk_sqw", | ||
1146 | .ops = &ds3231_clk_sqw_ops, | ||
1147 | .flags = CLK_IS_ROOT, | ||
1148 | }, | ||
1149 | [DS3231_CLK_32KHZ] = { | ||
1150 | .name = "ds3231_clk_32khz", | ||
1151 | .ops = &ds3231_clk_32khz_ops, | ||
1152 | .flags = CLK_IS_ROOT, | ||
1153 | }, | ||
1154 | }; | ||
1155 | |||
1156 | static int ds3231_clks_register(struct ds1307 *ds1307) | ||
1157 | { | ||
1158 | struct i2c_client *client = ds1307->client; | ||
1159 | struct device_node *node = client->dev.of_node; | ||
1160 | struct clk_onecell_data *onecell; | ||
1161 | int i; | ||
1162 | |||
1163 | onecell = devm_kzalloc(&client->dev, sizeof(*onecell), GFP_KERNEL); | ||
1164 | if (!onecell) | ||
1165 | return -ENOMEM; | ||
1166 | |||
1167 | onecell->clk_num = ARRAY_SIZE(ds3231_clks_init); | ||
1168 | onecell->clks = devm_kcalloc(&client->dev, onecell->clk_num, | ||
1169 | sizeof(onecell->clks[0]), GFP_KERNEL); | ||
1170 | if (!onecell->clks) | ||
1171 | return -ENOMEM; | ||
1172 | |||
1173 | for (i = 0; i < ARRAY_SIZE(ds3231_clks_init); i++) { | ||
1174 | struct clk_init_data init = ds3231_clks_init[i]; | ||
1175 | |||
1176 | /* | ||
1177 | * Interrupt signal due to alarm conditions and square-wave | ||
1178 | * output share same pin, so don't initialize both. | ||
1179 | */ | ||
1180 | if (i == DS3231_CLK_SQW && test_bit(HAS_ALARM, &ds1307->flags)) | ||
1181 | continue; | ||
1182 | |||
1183 | /* optional override of the clockname */ | ||
1184 | of_property_read_string_index(node, "clock-output-names", i, | ||
1185 | &init.name); | ||
1186 | ds1307->clks[i].init = &init; | ||
1187 | |||
1188 | onecell->clks[i] = devm_clk_register(&client->dev, | ||
1189 | &ds1307->clks[i]); | ||
1190 | if (IS_ERR(onecell->clks[i])) | ||
1191 | return PTR_ERR(onecell->clks[i]); | ||
1192 | } | ||
1193 | |||
1194 | if (!node) | ||
1195 | return 0; | ||
1196 | |||
1197 | of_clk_add_provider(node, of_clk_src_onecell_get, onecell); | ||
1198 | |||
1199 | return 0; | ||
1200 | } | ||
1201 | |||
1202 | static void ds1307_clks_register(struct ds1307 *ds1307) | ||
1203 | { | ||
1204 | int ret; | ||
1205 | |||
1206 | if (ds1307->type != ds_3231) | ||
1207 | return; | ||
1208 | |||
1209 | ret = ds3231_clks_register(ds1307); | ||
1210 | if (ret) { | ||
1211 | dev_warn(&ds1307->client->dev, | ||
1212 | "unable to register clock device %d\n", ret); | ||
1213 | } | ||
1214 | } | ||
1215 | |||
1216 | #else | ||
1217 | |||
1218 | static void ds1307_clks_register(struct ds1307 *ds1307) | ||
1219 | { | ||
1220 | } | ||
1221 | |||
1222 | #endif /* CONFIG_COMMON_CLK */ | ||
930 | 1223 | ||
931 | static int ds1307_probe(struct i2c_client *client, | 1224 | static int ds1307_probe(struct i2c_client *client, |
932 | const struct i2c_device_id *id) | 1225 | const struct i2c_device_id *id) |
@@ -1294,6 +1587,7 @@ read_rtc: | |||
1294 | } | 1587 | } |
1295 | 1588 | ||
1296 | ds1307_hwmon_register(ds1307); | 1589 | ds1307_hwmon_register(ds1307); |
1590 | ds1307_clks_register(ds1307); | ||
1297 | 1591 | ||
1298 | return 0; | 1592 | return 0; |
1299 | 1593 | ||