1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for Silicon Labs Si544 Programmable Oscillator 4 * Copyright (C) 2018 Topic Embedded Products 5 * Author: Mike Looijmans <mike.looijmans@topic.nl> 6 */ 7 8 #include <linux/clk-provider.h> 9 #include <linux/delay.h> 10 #include <linux/module.h> 11 #include <linux/i2c.h> 12 #include <linux/regmap.h> 13 #include <linux/slab.h> 14 15 /* I2C registers (decimal as in datasheet) */ 16 #define SI544_REG_CONTROL 7 17 #define SI544_REG_OE_STATE 17 18 #define SI544_REG_HS_DIV 23 19 #define SI544_REG_LS_HS_DIV 24 20 #define SI544_REG_FBDIV0 26 21 #define SI544_REG_FBDIV8 27 22 #define SI544_REG_FBDIV16 28 23 #define SI544_REG_FBDIV24 29 24 #define SI544_REG_FBDIV32 30 25 #define SI544_REG_FBDIV40 31 26 #define SI544_REG_FCAL_OVR 69 27 #define SI544_REG_ADPLL_DELTA_M0 231 28 #define SI544_REG_ADPLL_DELTA_M8 232 29 #define SI544_REG_ADPLL_DELTA_M16 233 30 #define SI544_REG_PAGE_SELECT 255 31 32 /* Register values */ 33 #define SI544_CONTROL_RESET BIT(7) 34 #define SI544_CONTROL_MS_ICAL2 BIT(3) 35 36 #define SI544_OE_STATE_ODC_OE BIT(0) 37 38 /* Max freq depends on speed grade */ 39 #define SI544_MIN_FREQ 200000U 40 41 /* Si544 Internal oscilator runs at 55.05 MHz */ 42 #define FXO 55050000U 43 44 /* VCO range is 10.8 .. 12.1 GHz, max depends on speed grade */ 45 #define FVCO_MIN 10800000000ULL 46 47 #define HS_DIV_MAX 2046 48 #define HS_DIV_MAX_ODD 33 49 50 /* Lowest frequency synthesizeable using only the HS divider */ 51 #define MIN_HSDIV_FREQ (FVCO_MIN / HS_DIV_MAX) 52 53 enum si544_speed_grade { 54 si544a, 55 si544b, 56 si544c, 57 }; 58 59 struct clk_si544 { 60 struct clk_hw hw; 61 struct regmap *regmap; 62 struct i2c_client *i2c_client; 63 enum si544_speed_grade speed_grade; 64 }; 65 #define to_clk_si544(_hw) container_of(_hw, struct clk_si544, hw) 66 67 /** 68 * struct clk_si544_muldiv - Multiplier/divider settings 69 * @fb_div_frac: integer part of feedback divider (32 bits) 70 * @fb_div_int: fractional part of feedback divider (11 bits) 71 * @hs_div: 1st divider, 5..2046, must be even when >33 72 * @ls_div_bits: 2nd divider, as 2^x, range 0..5 73 * If ls_div_bits is non-zero, hs_div must be even 74 */ 75 struct clk_si544_muldiv { 76 u32 fb_div_frac; 77 u16 fb_div_int; 78 u16 hs_div; 79 u8 ls_div_bits; 80 }; 81 82 /* Enables or disables the output driver */ 83 static int si544_enable_output(struct clk_si544 *data, bool enable) 84 { 85 return regmap_update_bits(data->regmap, SI544_REG_OE_STATE, 86 SI544_OE_STATE_ODC_OE, enable ? SI544_OE_STATE_ODC_OE : 0); 87 } 88 89 static int si544_prepare(struct clk_hw *hw) 90 { 91 struct clk_si544 *data = to_clk_si544(hw); 92 93 return si544_enable_output(data, true); 94 } 95 96 static void si544_unprepare(struct clk_hw *hw) 97 { 98 struct clk_si544 *data = to_clk_si544(hw); 99 100 si544_enable_output(data, false); 101 } 102 103 static int si544_is_prepared(struct clk_hw *hw) 104 { 105 struct clk_si544 *data = to_clk_si544(hw); 106 unsigned int val; 107 int err; 108 109 err = regmap_read(data->regmap, SI544_REG_OE_STATE, &val); 110 if (err < 0) 111 return err; 112 113 return !!(val & SI544_OE_STATE_ODC_OE); 114 } 115 116 /* Retrieve clock multiplier and dividers from hardware */ 117 static int si544_get_muldiv(struct clk_si544 *data, 118 struct clk_si544_muldiv *settings) 119 { 120 int err; 121 u8 reg[6]; 122 123 err = regmap_bulk_read(data->regmap, SI544_REG_HS_DIV, reg, 2); 124 if (err) 125 return err; 126 127 settings->ls_div_bits = (reg[1] >> 4) & 0x07; 128 settings->hs_div = (reg[1] & 0x07) << 8 | reg[0]; 129 130 err = regmap_bulk_read(data->regmap, SI544_REG_FBDIV0, reg, 6); 131 if (err) 132 return err; 133 134 settings->fb_div_int = reg[4] | (reg[5] & 0x07) << 8; 135 settings->fb_div_frac = reg[0] | reg[1] << 8 | reg[2] << 16 | 136 reg[3] << 24; 137 return 0; 138 } 139 140 static int si544_set_muldiv(struct clk_si544 *data, 141 struct clk_si544_muldiv *settings) 142 { 143 int err; 144 u8 reg[6]; 145 146 reg[0] = settings->hs_div; 147 reg[1] = settings->hs_div >> 8 | settings->ls_div_bits << 4; 148 149 err = regmap_bulk_write(data->regmap, SI544_REG_HS_DIV, reg, 2); 150 if (err < 0) 151 return err; 152 153 reg[0] = settings->fb_div_frac; 154 reg[1] = settings->fb_div_frac >> 8; 155 reg[2] = settings->fb_div_frac >> 16; 156 reg[3] = settings->fb_div_frac >> 24; 157 reg[4] = settings->fb_div_int; 158 reg[5] = settings->fb_div_int >> 8; 159 160 /* 161 * Writing to SI544_REG_FBDIV40 triggers the clock change, so that 162 * must be written last 163 */ 164 return regmap_bulk_write(data->regmap, SI544_REG_FBDIV0, reg, 6); 165 } 166 167 static bool is_valid_frequency(const struct clk_si544 *data, 168 unsigned long frequency) 169 { 170 unsigned long max_freq = 0; 171 172 if (frequency < SI544_MIN_FREQ) 173 return false; 174 175 switch (data->speed_grade) { 176 case si544a: 177 max_freq = 1500000000; 178 break; 179 case si544b: 180 max_freq = 800000000; 181 break; 182 case si544c: 183 max_freq = 350000000; 184 break; 185 } 186 187 return frequency <= max_freq; 188 } 189 190 /* Calculate divider settings for a given frequency */ 191 static int si544_calc_muldiv(struct clk_si544_muldiv *settings, 192 unsigned long frequency) 193 { 194 u64 vco; 195 u32 ls_freq; 196 u32 tmp; 197 u8 res; 198 199 /* Determine the minimum value of LS_DIV and resulting target freq. */ 200 ls_freq = frequency; 201 settings->ls_div_bits = 0; 202 203 if (frequency >= MIN_HSDIV_FREQ) { 204 settings->ls_div_bits = 0; 205 } else { 206 res = 1; 207 tmp = 2 * HS_DIV_MAX; 208 while (tmp <= (HS_DIV_MAX * 32)) { 209 if (((u64)frequency * tmp) >= FVCO_MIN) 210 break; 211 ++res; 212 tmp <<= 1; 213 } 214 settings->ls_div_bits = res; 215 ls_freq = frequency << res; 216 } 217 218 /* Determine minimum HS_DIV by rounding up */ 219 vco = FVCO_MIN + ls_freq - 1; 220 do_div(vco, ls_freq); 221 settings->hs_div = vco; 222 223 /* round up to even number when required */ 224 if ((settings->hs_div & 1) && 225 (settings->hs_div > HS_DIV_MAX_ODD || settings->ls_div_bits)) 226 ++settings->hs_div; 227 228 /* Calculate VCO frequency (in 10..12GHz range) */ 229 vco = (u64)ls_freq * settings->hs_div; 230 231 /* Calculate the integer part of the feedback divider */ 232 tmp = do_div(vco, FXO); 233 settings->fb_div_int = vco; 234 235 /* And the fractional bits using the remainder */ 236 vco = (u64)tmp << 32; 237 vco += FXO / 2; /* Round to nearest multiple */ 238 do_div(vco, FXO); 239 settings->fb_div_frac = vco; 240 241 return 0; 242 } 243 244 /* Calculate resulting frequency given the register settings */ 245 static unsigned long si544_calc_rate(struct clk_si544_muldiv *settings) 246 { 247 u32 d = settings->hs_div * BIT(settings->ls_div_bits); 248 u64 vco; 249 250 /* Calculate VCO from the fractional part */ 251 vco = (u64)settings->fb_div_frac * FXO; 252 vco += (FXO / 2); 253 vco >>= 32; 254 255 /* Add the integer part of the VCO frequency */ 256 vco += (u64)settings->fb_div_int * FXO; 257 258 /* Apply divider to obtain the generated frequency */ 259 do_div(vco, d); 260 261 return vco; 262 } 263 264 static unsigned long si544_recalc_rate(struct clk_hw *hw, 265 unsigned long parent_rate) 266 { 267 struct clk_si544 *data = to_clk_si544(hw); 268 struct clk_si544_muldiv settings; 269 int err; 270 271 err = si544_get_muldiv(data, &settings); 272 if (err) 273 return 0; 274 275 return si544_calc_rate(&settings); 276 } 277 278 static long si544_round_rate(struct clk_hw *hw, unsigned long rate, 279 unsigned long *parent_rate) 280 { 281 struct clk_si544 *data = to_clk_si544(hw); 282 struct clk_si544_muldiv settings; 283 int err; 284 285 if (!is_valid_frequency(data, rate)) 286 return -EINVAL; 287 288 err = si544_calc_muldiv(&settings, rate); 289 if (err) 290 return err; 291 292 return si544_calc_rate(&settings); 293 } 294 295 /* 296 * Update output frequency for "big" frequency changes 297 */ 298 static int si544_set_rate(struct clk_hw *hw, unsigned long rate, 299 unsigned long parent_rate) 300 { 301 struct clk_si544 *data = to_clk_si544(hw); 302 struct clk_si544_muldiv settings; 303 unsigned int old_oe_state; 304 int err; 305 306 if (!is_valid_frequency(data, rate)) 307 return -EINVAL; 308 309 err = si544_calc_muldiv(&settings, rate); 310 if (err) 311 return err; 312 313 err = regmap_read(data->regmap, SI544_REG_OE_STATE, &old_oe_state); 314 if (err) 315 return err; 316 317 si544_enable_output(data, false); 318 319 /* Allow FCAL for this frequency update */ 320 err = regmap_write(data->regmap, SI544_REG_FCAL_OVR, 0); 321 if (err < 0) 322 return err; 323 324 325 err = si544_set_muldiv(data, &settings); 326 if (err < 0) 327 return err; /* Undefined state now, best to leave disabled */ 328 329 /* Trigger calibration */ 330 err = regmap_write(data->regmap, SI544_REG_CONTROL, 331 SI544_CONTROL_MS_ICAL2); 332 if (err < 0) 333 return err; 334 335 /* Applying a new frequency can take up to 10ms */ 336 usleep_range(10000, 12000); 337 338 if (old_oe_state & SI544_OE_STATE_ODC_OE) 339 si544_enable_output(data, true); 340 341 return err; 342 } 343 344 static const struct clk_ops si544_clk_ops = { 345 .prepare = si544_prepare, 346 .unprepare = si544_unprepare, 347 .is_prepared = si544_is_prepared, 348 .recalc_rate = si544_recalc_rate, 349 .round_rate = si544_round_rate, 350 .set_rate = si544_set_rate, 351 }; 352 353 static bool si544_regmap_is_volatile(struct device *dev, unsigned int reg) 354 { 355 switch (reg) { 356 case SI544_REG_CONTROL: 357 case SI544_REG_FCAL_OVR: 358 return true; 359 default: 360 return false; 361 } 362 } 363 364 static const struct regmap_config si544_regmap_config = { 365 .reg_bits = 8, 366 .val_bits = 8, 367 .cache_type = REGCACHE_RBTREE, 368 .max_register = SI544_REG_PAGE_SELECT, 369 .volatile_reg = si544_regmap_is_volatile, 370 }; 371 372 static int si544_probe(struct i2c_client *client, 373 const struct i2c_device_id *id) 374 { 375 struct clk_si544 *data; 376 struct clk_init_data init; 377 int err; 378 379 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 380 if (!data) 381 return -ENOMEM; 382 383 init.ops = &si544_clk_ops; 384 init.flags = 0; 385 init.num_parents = 0; 386 data->hw.init = &init; 387 data->i2c_client = client; 388 data->speed_grade = id->driver_data; 389 390 if (of_property_read_string(client->dev.of_node, "clock-output-names", 391 &init.name)) 392 init.name = client->dev.of_node->name; 393 394 data->regmap = devm_regmap_init_i2c(client, &si544_regmap_config); 395 if (IS_ERR(data->regmap)) 396 return PTR_ERR(data->regmap); 397 398 i2c_set_clientdata(client, data); 399 400 /* Select page 0, just to be sure, there appear to be no more */ 401 err = regmap_write(data->regmap, SI544_REG_PAGE_SELECT, 0); 402 if (err < 0) 403 return err; 404 405 err = devm_clk_hw_register(&client->dev, &data->hw); 406 if (err) { 407 dev_err(&client->dev, "clock registration failed\n"); 408 return err; 409 } 410 err = devm_of_clk_add_hw_provider(&client->dev, of_clk_hw_simple_get, 411 &data->hw); 412 if (err) { 413 dev_err(&client->dev, "unable to add clk provider\n"); 414 return err; 415 } 416 417 return 0; 418 } 419 420 static const struct i2c_device_id si544_id[] = { 421 { "si544a", si544a }, 422 { "si544b", si544b }, 423 { "si544c", si544c }, 424 { } 425 }; 426 MODULE_DEVICE_TABLE(i2c, si544_id); 427 428 static const struct of_device_id clk_si544_of_match[] = { 429 { .compatible = "silabs,si544a" }, 430 { .compatible = "silabs,si544b" }, 431 { .compatible = "silabs,si544c" }, 432 { }, 433 }; 434 MODULE_DEVICE_TABLE(of, clk_si544_of_match); 435 436 static struct i2c_driver si544_driver = { 437 .driver = { 438 .name = "si544", 439 .of_match_table = clk_si544_of_match, 440 }, 441 .probe = si544_probe, 442 .id_table = si544_id, 443 }; 444 module_i2c_driver(si544_driver); 445 446 MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>"); 447 MODULE_DESCRIPTION("Si544 driver"); 448 MODULE_LICENSE("GPL"); 449