0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk-provider.h>
0011 #include <linux/delay.h>
0012 #include <linux/module.h>
0013 #include <linux/i2c.h>
0014 #include <linux/regmap.h>
0015 #include <linux/slab.h>
0016
0017
0018 #define SI514_REG_LP 0
0019 #define SI514_REG_M_FRAC1 5
0020 #define SI514_REG_M_FRAC2 6
0021 #define SI514_REG_M_FRAC3 7
0022 #define SI514_REG_M_INT_FRAC 8
0023 #define SI514_REG_M_INT 9
0024 #define SI514_REG_HS_DIV 10
0025 #define SI514_REG_LS_HS_DIV 11
0026 #define SI514_REG_OE_STATE 14
0027 #define SI514_REG_RESET 128
0028 #define SI514_REG_CONTROL 132
0029
0030
0031 #define SI514_RESET_RST BIT(7)
0032
0033 #define SI514_CONTROL_FCAL BIT(0)
0034 #define SI514_CONTROL_OE BIT(2)
0035
0036 #define SI514_MIN_FREQ 100000U
0037 #define SI514_MAX_FREQ 250000000U
0038
0039 #define FXO 31980000U
0040
0041 #define FVCO_MIN 2080000000U
0042 #define FVCO_MAX 2500000000U
0043
0044 #define HS_DIV_MAX 1022
0045
0046 struct clk_si514 {
0047 struct clk_hw hw;
0048 struct regmap *regmap;
0049 struct i2c_client *i2c_client;
0050 };
0051 #define to_clk_si514(_hw) container_of(_hw, struct clk_si514, hw)
0052
0053
0054 struct clk_si514_muldiv {
0055 u32 m_frac;
0056 u8 m_int;
0057 u8 ls_div_bits;
0058 u16 hs_div;
0059 };
0060
0061
0062 static int si514_enable_output(struct clk_si514 *data, bool enable)
0063 {
0064 return regmap_update_bits(data->regmap, SI514_REG_CONTROL,
0065 SI514_CONTROL_OE, enable ? SI514_CONTROL_OE : 0);
0066 }
0067
0068 static int si514_prepare(struct clk_hw *hw)
0069 {
0070 struct clk_si514 *data = to_clk_si514(hw);
0071
0072 return si514_enable_output(data, true);
0073 }
0074
0075 static void si514_unprepare(struct clk_hw *hw)
0076 {
0077 struct clk_si514 *data = to_clk_si514(hw);
0078
0079 si514_enable_output(data, false);
0080 }
0081
0082 static int si514_is_prepared(struct clk_hw *hw)
0083 {
0084 struct clk_si514 *data = to_clk_si514(hw);
0085 unsigned int val;
0086 int err;
0087
0088 err = regmap_read(data->regmap, SI514_REG_CONTROL, &val);
0089 if (err < 0)
0090 return err;
0091
0092 return !!(val & SI514_CONTROL_OE);
0093 }
0094
0095
0096 static int si514_get_muldiv(struct clk_si514 *data,
0097 struct clk_si514_muldiv *settings)
0098 {
0099 int err;
0100 u8 reg[7];
0101
0102 err = regmap_bulk_read(data->regmap, SI514_REG_M_FRAC1,
0103 reg, ARRAY_SIZE(reg));
0104 if (err)
0105 return err;
0106
0107 settings->m_frac = reg[0] | reg[1] << 8 | reg[2] << 16 |
0108 (reg[3] & 0x1F) << 24;
0109 settings->m_int = (reg[4] & 0x3f) << 3 | reg[3] >> 5;
0110 settings->ls_div_bits = (reg[6] >> 4) & 0x07;
0111 settings->hs_div = (reg[6] & 0x03) << 8 | reg[5];
0112 return 0;
0113 }
0114
0115 static int si514_set_muldiv(struct clk_si514 *data,
0116 struct clk_si514_muldiv *settings)
0117 {
0118 u8 lp;
0119 u8 reg[7];
0120 int err;
0121
0122
0123
0124 if (settings->m_int < 65 ||
0125 (settings->m_int == 65 && settings->m_frac <= 139575831))
0126 lp = 0x22;
0127
0128 else if (settings->m_int < 67 ||
0129 (settings->m_int == 67 && settings->m_frac <= 461581994))
0130 lp = 0x23;
0131
0132 else if (settings->m_int < 72 ||
0133 (settings->m_int == 72 && settings->m_frac <= 503383578))
0134 lp = 0x33;
0135
0136 else if (settings->m_int < 75 ||
0137 (settings->m_int == 75 && settings->m_frac <= 452724474))
0138 lp = 0x34;
0139 else
0140 lp = 0x44;
0141
0142 err = regmap_write(data->regmap, SI514_REG_LP, lp);
0143 if (err < 0)
0144 return err;
0145
0146 reg[0] = settings->m_frac;
0147 reg[1] = settings->m_frac >> 8;
0148 reg[2] = settings->m_frac >> 16;
0149 reg[3] = settings->m_frac >> 24 | settings->m_int << 5;
0150 reg[4] = settings->m_int >> 3;
0151 reg[5] = settings->hs_div;
0152 reg[6] = (settings->hs_div >> 8) | (settings->ls_div_bits << 4);
0153
0154 err = regmap_bulk_write(data->regmap, SI514_REG_HS_DIV, reg + 5, 2);
0155 if (err < 0)
0156 return err;
0157
0158
0159
0160
0161 return regmap_bulk_write(data->regmap, SI514_REG_M_FRAC1, reg, 5);
0162 }
0163
0164
0165 static int si514_calc_muldiv(struct clk_si514_muldiv *settings,
0166 unsigned long frequency)
0167 {
0168 u64 m;
0169 u32 ls_freq;
0170 u32 tmp;
0171 u8 res;
0172
0173 if ((frequency < SI514_MIN_FREQ) || (frequency > SI514_MAX_FREQ))
0174 return -EINVAL;
0175
0176
0177 ls_freq = frequency;
0178 if (frequency >= (FVCO_MIN / HS_DIV_MAX))
0179 settings->ls_div_bits = 0;
0180 else {
0181 res = 1;
0182 tmp = 2 * HS_DIV_MAX;
0183 while (tmp <= (HS_DIV_MAX * 32)) {
0184 if ((frequency * tmp) >= FVCO_MIN)
0185 break;
0186 ++res;
0187 tmp <<= 1;
0188 }
0189 settings->ls_div_bits = res;
0190 ls_freq = frequency << res;
0191 }
0192
0193
0194 settings->hs_div = DIV_ROUND_UP(FVCO_MIN >> 1, ls_freq) << 1;
0195
0196
0197 m = ((u64)(ls_freq * settings->hs_div) << 29) + (FXO / 2);
0198 do_div(m, FXO);
0199 settings->m_frac = (u32)m & (BIT(29) - 1);
0200 settings->m_int = (u32)(m >> 29);
0201
0202 return 0;
0203 }
0204
0205
0206 static unsigned long si514_calc_rate(struct clk_si514_muldiv *settings)
0207 {
0208 u64 m = settings->m_frac | ((u64)settings->m_int << 29);
0209 u32 d = settings->hs_div * BIT(settings->ls_div_bits);
0210
0211 return ((u32)(((m * FXO) + (FXO / 2)) >> 29)) / d;
0212 }
0213
0214 static unsigned long si514_recalc_rate(struct clk_hw *hw,
0215 unsigned long parent_rate)
0216 {
0217 struct clk_si514 *data = to_clk_si514(hw);
0218 struct clk_si514_muldiv settings;
0219 int err;
0220
0221 err = si514_get_muldiv(data, &settings);
0222 if (err) {
0223 dev_err(&data->i2c_client->dev, "unable to retrieve settings\n");
0224 return 0;
0225 }
0226
0227 return si514_calc_rate(&settings);
0228 }
0229
0230 static long si514_round_rate(struct clk_hw *hw, unsigned long rate,
0231 unsigned long *parent_rate)
0232 {
0233 struct clk_si514_muldiv settings;
0234 int err;
0235
0236 if (!rate)
0237 return 0;
0238
0239 err = si514_calc_muldiv(&settings, rate);
0240 if (err)
0241 return err;
0242
0243 return si514_calc_rate(&settings);
0244 }
0245
0246
0247
0248
0249
0250
0251 static int si514_set_rate(struct clk_hw *hw, unsigned long rate,
0252 unsigned long parent_rate)
0253 {
0254 struct clk_si514 *data = to_clk_si514(hw);
0255 struct clk_si514_muldiv settings;
0256 unsigned int old_oe_state;
0257 int err;
0258
0259 err = si514_calc_muldiv(&settings, rate);
0260 if (err)
0261 return err;
0262
0263 err = regmap_read(data->regmap, SI514_REG_CONTROL, &old_oe_state);
0264 if (err)
0265 return err;
0266
0267 si514_enable_output(data, false);
0268
0269 err = si514_set_muldiv(data, &settings);
0270 if (err < 0)
0271 return err;
0272
0273
0274 err = regmap_write(data->regmap, SI514_REG_CONTROL, SI514_CONTROL_FCAL);
0275 if (err < 0)
0276 return err;
0277
0278
0279 usleep_range(10000, 12000);
0280
0281 if (old_oe_state & SI514_CONTROL_OE)
0282 si514_enable_output(data, true);
0283
0284 return err;
0285 }
0286
0287 static const struct clk_ops si514_clk_ops = {
0288 .prepare = si514_prepare,
0289 .unprepare = si514_unprepare,
0290 .is_prepared = si514_is_prepared,
0291 .recalc_rate = si514_recalc_rate,
0292 .round_rate = si514_round_rate,
0293 .set_rate = si514_set_rate,
0294 };
0295
0296 static bool si514_regmap_is_volatile(struct device *dev, unsigned int reg)
0297 {
0298 switch (reg) {
0299 case SI514_REG_CONTROL:
0300 case SI514_REG_RESET:
0301 return true;
0302 default:
0303 return false;
0304 }
0305 }
0306
0307 static bool si514_regmap_is_writeable(struct device *dev, unsigned int reg)
0308 {
0309 switch (reg) {
0310 case SI514_REG_LP:
0311 case SI514_REG_M_FRAC1 ... SI514_REG_LS_HS_DIV:
0312 case SI514_REG_OE_STATE:
0313 case SI514_REG_RESET:
0314 case SI514_REG_CONTROL:
0315 return true;
0316 default:
0317 return false;
0318 }
0319 }
0320
0321 static const struct regmap_config si514_regmap_config = {
0322 .reg_bits = 8,
0323 .val_bits = 8,
0324 .cache_type = REGCACHE_RBTREE,
0325 .max_register = SI514_REG_CONTROL,
0326 .writeable_reg = si514_regmap_is_writeable,
0327 .volatile_reg = si514_regmap_is_volatile,
0328 };
0329
0330 static int si514_probe(struct i2c_client *client)
0331 {
0332 struct clk_si514 *data;
0333 struct clk_init_data init;
0334 int err;
0335
0336 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
0337 if (!data)
0338 return -ENOMEM;
0339
0340 init.ops = &si514_clk_ops;
0341 init.flags = 0;
0342 init.num_parents = 0;
0343 data->hw.init = &init;
0344 data->i2c_client = client;
0345
0346 if (of_property_read_string(client->dev.of_node, "clock-output-names",
0347 &init.name))
0348 init.name = client->dev.of_node->name;
0349
0350 data->regmap = devm_regmap_init_i2c(client, &si514_regmap_config);
0351 if (IS_ERR(data->regmap)) {
0352 dev_err(&client->dev, "failed to allocate register map\n");
0353 return PTR_ERR(data->regmap);
0354 }
0355
0356 i2c_set_clientdata(client, data);
0357
0358 err = devm_clk_hw_register(&client->dev, &data->hw);
0359 if (err) {
0360 dev_err(&client->dev, "clock registration failed\n");
0361 return err;
0362 }
0363 err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get,
0364 &data->hw);
0365 if (err) {
0366 dev_err(&client->dev, "unable to add clk provider\n");
0367 return err;
0368 }
0369
0370 return 0;
0371 }
0372
0373 static int si514_remove(struct i2c_client *client)
0374 {
0375 of_clk_del_provider(client->dev.of_node);
0376 return 0;
0377 }
0378
0379 static const struct i2c_device_id si514_id[] = {
0380 { "si514", 0 },
0381 { }
0382 };
0383 MODULE_DEVICE_TABLE(i2c, si514_id);
0384
0385 static const struct of_device_id clk_si514_of_match[] = {
0386 { .compatible = "silabs,si514" },
0387 { },
0388 };
0389 MODULE_DEVICE_TABLE(of, clk_si514_of_match);
0390
0391 static struct i2c_driver si514_driver = {
0392 .driver = {
0393 .name = "si514",
0394 .of_match_table = clk_si514_of_match,
0395 },
0396 .probe_new = si514_probe,
0397 .remove = si514_remove,
0398 .id_table = si514_id,
0399 };
0400 module_i2c_driver(si514_driver);
0401
0402 MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
0403 MODULE_DESCRIPTION("Si514 driver");
0404 MODULE_LICENSE("GPL");