1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Common clock framework driver for the Versaclock7 family of timing devices. 4 * 5 * Copyright (c) 2022 Renesas Electronics Corporation 6 */ 7 8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 10 #include <linux/bitfield.h> 11 #include <linux/clk.h> 12 #include <linux/clk-provider.h> 13 #include <linux/i2c.h> 14 #include <linux/math64.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/of_platform.h> 18 #include <linux/property.h> 19 #include <linux/regmap.h> 20 #include <linux/swab.h> 21 22 /* 23 * 16-bit register address: the lower 8 bits of the register address come 24 * from the offset addr byte and the upper 8 bits come from the page register. 25 */ 26 #define VC7_PAGE_ADDR 0xFD 27 #define VC7_PAGE_WINDOW 256 28 #define VC7_MAX_REG 0x364 29 30 /* Maximum number of banks supported by VC7 */ 31 #define VC7_NUM_BANKS 7 32 33 /* Maximum number of FODs supported by VC7 */ 34 #define VC7_NUM_FOD 3 35 36 /* Maximum number of IODs supported by VC7 */ 37 #define VC7_NUM_IOD 4 38 39 /* Maximum number of outputs supported by VC7 */ 40 #define VC7_NUM_OUT 12 41 42 /* VCO valid range is 9.5 GHz to 10.7 GHz */ 43 #define VC7_APLL_VCO_MIN 9500000000UL 44 #define VC7_APLL_VCO_MAX 10700000000UL 45 46 /* APLL denominator is fixed at 2^27 */ 47 #define VC7_APLL_DENOMINATOR_BITS 27 48 49 /* FOD 1st stage denominator is fixed 2^34 */ 50 #define VC7_FOD_DENOMINATOR_BITS 34 51 52 /* IOD can operate between 1kHz and 650MHz */ 53 #define VC7_IOD_RATE_MIN 1000UL 54 #define VC7_IOD_RATE_MAX 650000000UL 55 #define VC7_IOD_MIN_DIVISOR 14 56 #define VC7_IOD_MAX_DIVISOR 0x1ffffff /* 25-bit */ 57 58 #define VC7_FOD_RATE_MIN 1000UL 59 #define VC7_FOD_RATE_MAX 650000000UL 60 #define VC7_FOD_1ST_STAGE_RATE_MIN 33000000UL /* 33 MHz */ 61 #define VC7_FOD_1ST_STAGE_RATE_MAX 650000000UL /* 650 MHz */ 62 #define VC7_FOD_1ST_INT_MAX 324 63 #define VC7_FOD_2ND_INT_MIN 2 64 #define VC7_FOD_2ND_INT_MAX 0x1ffff /* 17-bit */ 65 66 /* VC7 Registers */ 67 68 #define VC7_REG_XO_CNFG 0x2C 69 #define VC7_REG_XO_CNFG_COUNT 4 70 #define VC7_REG_XO_IB_H_DIV_SHIFT 24 71 #define VC7_REG_XO_IB_H_DIV_MASK GENMASK(28, VC7_REG_XO_IB_H_DIV_SHIFT) 72 73 #define VC7_REG_APLL_FB_DIV_FRAC 0x120 74 #define VC7_REG_APLL_FB_DIV_FRAC_COUNT 4 75 #define VC7_REG_APLL_FB_DIV_FRAC_MASK GENMASK(26, 0) 76 77 #define VC7_REG_APLL_FB_DIV_INT 0x124 78 #define VC7_REG_APLL_FB_DIV_INT_COUNT 2 79 #define VC7_REG_APLL_FB_DIV_INT_MASK GENMASK(9, 0) 80 81 #define VC7_REG_APLL_CNFG 0x127 82 #define VC7_REG_APLL_EN_DOUBLER BIT(0) 83 84 #define VC7_REG_OUT_BANK_CNFG(idx) (0x280 + (0x4 * (idx))) 85 #define VC7_REG_OUTPUT_BANK_SRC_MASK GENMASK(2, 0) 86 87 #define VC7_REG_FOD_INT_CNFG(idx) (0x1E0 + (0x10 * (idx))) 88 #define VC7_REG_FOD_INT_CNFG_COUNT 8 89 #define VC7_REG_FOD_1ST_INT_MASK GENMASK(8, 0) 90 #define VC7_REG_FOD_2ND_INT_SHIFT 9 91 #define VC7_REG_FOD_2ND_INT_MASK GENMASK(25, VC7_REG_FOD_2ND_INT_SHIFT) 92 #define VC7_REG_FOD_FRAC_SHIFT 26 93 #define VC7_REG_FOD_FRAC_MASK GENMASK_ULL(59, VC7_REG_FOD_FRAC_SHIFT) 94 95 #define VC7_REG_IOD_INT_CNFG(idx) (0x1C0 + (0x8 * (idx))) 96 #define VC7_REG_IOD_INT_CNFG_COUNT 4 97 #define VC7_REG_IOD_INT_MASK GENMASK(24, 0) 98 99 #define VC7_REG_ODRV_EN(idx) (0x240 + (0x4 * (idx))) 100 #define VC7_REG_OUT_DIS BIT(0) 101 102 struct vc7_driver_data; 103 static const struct regmap_config vc7_regmap_config; 104 105 /* Supported Renesas VC7 models */ 106 enum vc7_model { 107 VC7_RC21008A, 108 }; 109 110 struct vc7_chip_info { 111 const enum vc7_model model; 112 const unsigned int banks[VC7_NUM_BANKS]; 113 const unsigned int num_banks; 114 const unsigned int outputs[VC7_NUM_OUT]; 115 const unsigned int num_outputs; 116 }; 117 118 /* 119 * Changing the APLL frequency is currently not supported. 120 * The APLL will consist of an opaque block between the XO and FOD/IODs and 121 * its frequency will be computed based on the current state of the device. 122 */ 123 struct vc7_apll_data { 124 struct clk *clk; 125 struct vc7_driver_data *vc7; 126 u8 xo_ib_h_div; 127 u8 en_doubler; 128 u16 apll_fb_div_int; 129 u32 apll_fb_div_frac; 130 }; 131 132 struct vc7_fod_data { 133 struct clk_hw hw; 134 struct vc7_driver_data *vc7; 135 unsigned int num; 136 u32 fod_1st_int; 137 u32 fod_2nd_int; 138 u64 fod_frac; 139 }; 140 141 struct vc7_iod_data { 142 struct clk_hw hw; 143 struct vc7_driver_data *vc7; 144 unsigned int num; 145 u32 iod_int; 146 }; 147 148 struct vc7_out_data { 149 struct clk_hw hw; 150 struct vc7_driver_data *vc7; 151 unsigned int num; 152 unsigned int out_dis; 153 }; 154 155 struct vc7_driver_data { 156 struct i2c_client *client; 157 struct regmap *regmap; 158 const struct vc7_chip_info *chip_info; 159 160 struct clk *pin_xin; 161 struct vc7_apll_data clk_apll; 162 struct vc7_fod_data clk_fod[VC7_NUM_FOD]; 163 struct vc7_iod_data clk_iod[VC7_NUM_IOD]; 164 struct vc7_out_data clk_out[VC7_NUM_OUT]; 165 }; 166 167 struct vc7_bank_src_map { 168 enum vc7_bank_src_type { 169 VC7_FOD, 170 VC7_IOD, 171 } type; 172 union _divider { 173 struct vc7_iod_data *iod; 174 struct vc7_fod_data *fod; 175 } src; 176 }; 177 178 static struct clk_hw *vc7_of_clk_get(struct of_phandle_args *clkspec, 179 void *data) 180 { 181 struct vc7_driver_data *vc7 = data; 182 unsigned int idx = clkspec->args[0]; 183 184 if (idx >= vc7->chip_info->num_outputs) 185 return ERR_PTR(-EINVAL); 186 187 return &vc7->clk_out[idx].hw; 188 } 189 190 static const unsigned int RC21008A_index_to_output_mapping[] = { 191 1, 2, 3, 6, 7, 8, 10, 11 192 }; 193 194 static int vc7_map_index_to_output(const enum vc7_model model, const unsigned int i) 195 { 196 switch (model) { 197 case VC7_RC21008A: 198 return RC21008A_index_to_output_mapping[i]; 199 default: 200 return i; 201 } 202 } 203 204 /* bank to output mapping, same across all variants */ 205 static const unsigned int output_bank_mapping[] = { 206 0, /* Output 0 */ 207 1, /* Output 1 */ 208 2, /* Output 2 */ 209 2, /* Output 3 */ 210 3, /* Output 4 */ 211 3, /* Output 5 */ 212 3, /* Output 6 */ 213 3, /* Output 7 */ 214 4, /* Output 8 */ 215 4, /* Output 9 */ 216 5, /* Output 10 */ 217 6 /* Output 11 */ 218 }; 219 220 /** 221 * vc7_64_mul_64_to_128() - Multiply two u64 and return an unsigned 128-bit integer 222 * as an upper and lower part. 223 * 224 * @left: The left argument. 225 * @right: The right argument. 226 * @hi: The upper 64-bits of the 128-bit product. 227 * @lo: The lower 64-bits of the 128-bit product. 228 * 229 * From mul_64_64 in crypto/ecc.c:350 in the linux kernel, accessed in v5.17.2. 230 */ 231 static void vc7_64_mul_64_to_128(u64 left, u64 right, u64 *hi, u64 *lo) 232 { 233 u64 a0 = left & 0xffffffffull; 234 u64 a1 = left >> 32; 235 u64 b0 = right & 0xffffffffull; 236 u64 b1 = right >> 32; 237 u64 m0 = a0 * b0; 238 u64 m1 = a0 * b1; 239 u64 m2 = a1 * b0; 240 u64 m3 = a1 * b1; 241 242 m2 += (m0 >> 32); 243 m2 += m1; 244 245 /* Overflow */ 246 if (m2 < m1) 247 m3 += 0x100000000ull; 248 249 *lo = (m0 & 0xffffffffull) | (m2 << 32); 250 *hi = m3 + (m2 >> 32); 251 } 252 253 /** 254 * vc7_128_div_64_to_64() - Divides a 128-bit uint by a 64-bit divisor, return a 64-bit quotient. 255 * 256 * @numhi: The uppper 64-bits of the dividend. 257 * @numlo: The lower 64-bits of the dividend. 258 * @den: The denominator (divisor). 259 * @r: The remainder, pass NULL if the remainder is not needed. 260 * 261 * Originally from libdivide, modified to use kernel u64/u32 types. 262 * 263 * See https://github.com/ridiculousfish/libdivide/blob/master/libdivide.h#L471. 264 * 265 * Return: The 64-bit quotient of the division. 266 * 267 * In case of overflow of division by zero, max(u64) is returned. 268 */ 269 static u64 vc7_128_div_64_to_64(u64 numhi, u64 numlo, u64 den, u64 *r) 270 { 271 /* 272 * We work in base 2**32. 273 * A uint32 holds a single digit. A uint64 holds two digits. 274 * Our numerator is conceptually [num3, num2, num1, num0]. 275 * Our denominator is [den1, den0]. 276 */ 277 const u64 b = ((u64)1 << 32); 278 279 /* The high and low digits of our computed quotient. */ 280 u32 q1, q0; 281 282 /* The normalization shift factor */ 283 int shift; 284 285 /* 286 * The high and low digits of our denominator (after normalizing). 287 * Also the low 2 digits of our numerator (after normalizing). 288 */ 289 u32 den1, den0, num1, num0; 290 291 /* A partial remainder; */ 292 u64 rem; 293 294 /* 295 * The estimated quotient, and its corresponding remainder (unrelated 296 * to true remainder). 297 */ 298 u64 qhat, rhat; 299 300 /* Variables used to correct the estimated quotient. */ 301 u64 c1, c2; 302 303 /* Check for overflow and divide by 0. */ 304 if (numhi >= den) { 305 if (r) 306 *r = ~0ull; 307 return ~0ull; 308 } 309 310 /* 311 * Determine the normalization factor. We multiply den by this, so that 312 * its leading digit is at least half b. In binary this means just 313 * shifting left by the number of leading zeros, so that there's a 1 in 314 * the MSB. 315 * 316 * We also shift numer by the same amount. This cannot overflow because 317 * numhi < den. The expression (-shift & 63) is the same as (64 - 318 * shift), except it avoids the UB of shifting by 64. The funny bitwise 319 * 'and' ensures that numlo does not get shifted into numhi if shift is 320 * 0. clang 11 has an x86 codegen bug here: see LLVM bug 50118. The 321 * sequence below avoids it. 322 */ 323 shift = __builtin_clzll(den); 324 den <<= shift; 325 numhi <<= shift; 326 numhi |= (numlo >> (-shift & 63)) & (-(s64)shift >> 63); 327 numlo <<= shift; 328 329 /* 330 * Extract the low digits of the numerator and both digits of the 331 * denominator. 332 */ 333 num1 = (u32)(numlo >> 32); 334 num0 = (u32)(numlo & 0xFFFFFFFFu); 335 den1 = (u32)(den >> 32); 336 den0 = (u32)(den & 0xFFFFFFFFu); 337 338 /* 339 * We wish to compute q1 = [n3 n2 n1] / [d1 d0]. 340 * Estimate q1 as [n3 n2] / [d1], and then correct it. 341 * Note while qhat may be 2 digits, q1 is always 1 digit. 342 */ 343 qhat = div64_u64_rem(numhi, den1, &rhat); 344 c1 = qhat * den0; 345 c2 = rhat * b + num1; 346 if (c1 > c2) 347 qhat -= (c1 - c2 > den) ? 2 : 1; 348 q1 = (u32)qhat; 349 350 /* Compute the true (partial) remainder. */ 351 rem = numhi * b + num1 - q1 * den; 352 353 /* 354 * We wish to compute q0 = [rem1 rem0 n0] / [d1 d0]. 355 * Estimate q0 as [rem1 rem0] / [d1] and correct it. 356 */ 357 qhat = div64_u64_rem(rem, den1, &rhat); 358 c1 = qhat * den0; 359 c2 = rhat * b + num0; 360 if (c1 > c2) 361 qhat -= (c1 - c2 > den) ? 2 : 1; 362 q0 = (u32)qhat; 363 364 /* Return remainder if requested. */ 365 if (r) 366 *r = (rem * b + num0 - q0 * den) >> shift; 367 return ((u64)q1 << 32) | q0; 368 } 369 370 static int vc7_get_bank_clk(struct vc7_driver_data *vc7, 371 unsigned int bank_idx, 372 unsigned int output_bank_src, 373 struct vc7_bank_src_map *map) 374 { 375 /* Mapping from Table 38 in datasheet */ 376 if (bank_idx == 0 || bank_idx == 1) { 377 switch (output_bank_src) { 378 case 0: 379 map->type = VC7_IOD, 380 map->src.iod = &vc7->clk_iod[0]; 381 return 0; 382 case 1: 383 map->type = VC7_IOD, 384 map->src.iod = &vc7->clk_iod[1]; 385 return 0; 386 case 4: 387 map->type = VC7_FOD, 388 map->src.fod = &vc7->clk_fod[0]; 389 return 0; 390 case 5: 391 map->type = VC7_FOD, 392 map->src.fod = &vc7->clk_fod[1]; 393 return 0; 394 default: 395 break; 396 } 397 } else if (bank_idx == 2) { 398 switch (output_bank_src) { 399 case 1: 400 map->type = VC7_IOD, 401 map->src.iod = &vc7->clk_iod[1]; 402 return 0; 403 case 4: 404 map->type = VC7_FOD, 405 map->src.fod = &vc7->clk_fod[0]; 406 return 0; 407 case 5: 408 map->type = VC7_FOD, 409 map->src.fod = &vc7->clk_fod[1]; 410 return 0; 411 default: 412 break; 413 } 414 } else if (bank_idx == 3) { 415 switch (output_bank_src) { 416 case 4: 417 map->type = VC7_FOD, 418 map->src.fod = &vc7->clk_fod[0]; 419 return 0; 420 case 5: 421 map->type = VC7_FOD, 422 map->src.fod = &vc7->clk_fod[1]; 423 return 0; 424 case 6: 425 map->type = VC7_FOD, 426 map->src.fod = &vc7->clk_fod[2]; 427 return 0; 428 default: 429 break; 430 } 431 } else if (bank_idx == 4) { 432 switch (output_bank_src) { 433 case 0: 434 /* CLKIN1 not supported in this driver */ 435 break; 436 case 2: 437 map->type = VC7_IOD, 438 map->src.iod = &vc7->clk_iod[2]; 439 return 0; 440 case 5: 441 map->type = VC7_FOD, 442 map->src.fod = &vc7->clk_fod[1]; 443 return 0; 444 case 6: 445 map->type = VC7_FOD, 446 map->src.fod = &vc7->clk_fod[2]; 447 return 0; 448 case 7: 449 /* CLKIN0 not supported in this driver */ 450 break; 451 default: 452 break; 453 } 454 } else if (bank_idx == 5) { 455 switch (output_bank_src) { 456 case 0: 457 /* CLKIN1 not supported in this driver */ 458 break; 459 case 1: 460 /* XIN_REFIN not supported in this driver */ 461 break; 462 case 2: 463 map->type = VC7_IOD, 464 map->src.iod = &vc7->clk_iod[2]; 465 return 0; 466 case 3: 467 map->type = VC7_IOD, 468 map->src.iod = &vc7->clk_iod[3]; 469 return 0; 470 case 5: 471 map->type = VC7_FOD, 472 map->src.fod = &vc7->clk_fod[1]; 473 return 0; 474 case 6: 475 map->type = VC7_FOD, 476 map->src.fod = &vc7->clk_fod[2]; 477 return 0; 478 case 7: 479 /* CLKIN0 not supported in this driver */ 480 break; 481 default: 482 break; 483 } 484 } else if (bank_idx == 6) { 485 switch (output_bank_src) { 486 case 0: 487 /* CLKIN1 not supported in this driver */ 488 break; 489 case 2: 490 map->type = VC7_IOD, 491 map->src.iod = &vc7->clk_iod[2]; 492 return 0; 493 case 3: 494 map->type = VC7_IOD, 495 map->src.iod = &vc7->clk_iod[3]; 496 return 0; 497 case 5: 498 map->type = VC7_FOD, 499 map->src.fod = &vc7->clk_fod[1]; 500 return 0; 501 case 6: 502 map->type = VC7_FOD, 503 map->src.fod = &vc7->clk_fod[2]; 504 return 0; 505 case 7: 506 /* CLKIN0 not supported in this driver */ 507 break; 508 default: 509 break; 510 } 511 } 512 513 pr_warn("bank_src%d = %d is not supported\n", bank_idx, output_bank_src); 514 return -1; 515 } 516 517 static int vc7_read_apll(struct vc7_driver_data *vc7) 518 { 519 int err; 520 u32 val32; 521 u16 val16; 522 523 err = regmap_bulk_read(vc7->regmap, 524 VC7_REG_XO_CNFG, 525 (u32 *)&val32, 526 VC7_REG_XO_CNFG_COUNT); 527 if (err) { 528 dev_err(&vc7->client->dev, "failed to read XO_CNFG\n"); 529 return err; 530 } 531 532 vc7->clk_apll.xo_ib_h_div = (val32 & VC7_REG_XO_IB_H_DIV_MASK) 533 >> VC7_REG_XO_IB_H_DIV_SHIFT; 534 535 err = regmap_read(vc7->regmap, 536 VC7_REG_APLL_CNFG, 537 &val32); 538 if (err) { 539 dev_err(&vc7->client->dev, "failed to read APLL_CNFG\n"); 540 return err; 541 } 542 543 vc7->clk_apll.en_doubler = val32 & VC7_REG_APLL_EN_DOUBLER; 544 545 err = regmap_bulk_read(vc7->regmap, 546 VC7_REG_APLL_FB_DIV_FRAC, 547 (u32 *)&val32, 548 VC7_REG_APLL_FB_DIV_FRAC_COUNT); 549 if (err) { 550 dev_err(&vc7->client->dev, "failed to read APLL_FB_DIV_FRAC\n"); 551 return err; 552 } 553 554 vc7->clk_apll.apll_fb_div_frac = val32 & VC7_REG_APLL_FB_DIV_FRAC_MASK; 555 556 err = regmap_bulk_read(vc7->regmap, 557 VC7_REG_APLL_FB_DIV_INT, 558 (u16 *)&val16, 559 VC7_REG_APLL_FB_DIV_INT_COUNT); 560 if (err) { 561 dev_err(&vc7->client->dev, "failed to read APLL_FB_DIV_INT\n"); 562 return err; 563 } 564 565 vc7->clk_apll.apll_fb_div_int = val16 & VC7_REG_APLL_FB_DIV_INT_MASK; 566 567 return 0; 568 } 569 570 static int vc7_read_fod(struct vc7_driver_data *vc7, unsigned int idx) 571 { 572 int err; 573 u64 val; 574 575 err = regmap_bulk_read(vc7->regmap, 576 VC7_REG_FOD_INT_CNFG(idx), 577 (u64 *)&val, 578 VC7_REG_FOD_INT_CNFG_COUNT); 579 if (err) { 580 dev_err(&vc7->client->dev, "failed to read FOD%d\n", idx); 581 return err; 582 } 583 584 vc7->clk_fod[idx].fod_1st_int = (val & VC7_REG_FOD_1ST_INT_MASK); 585 vc7->clk_fod[idx].fod_2nd_int = 586 (val & VC7_REG_FOD_2ND_INT_MASK) >> VC7_REG_FOD_2ND_INT_SHIFT; 587 vc7->clk_fod[idx].fod_frac = (val & VC7_REG_FOD_FRAC_MASK) 588 >> VC7_REG_FOD_FRAC_SHIFT; 589 590 return 0; 591 } 592 593 static int vc7_write_fod(struct vc7_driver_data *vc7, unsigned int idx) 594 { 595 int err; 596 u64 val; 597 598 /* 599 * FOD dividers are part of an atomic group where fod_1st_int, 600 * fod_2nd_int, and fod_frac must be written together. The new divider 601 * is applied when the MSB of fod_frac is written. 602 */ 603 604 err = regmap_bulk_read(vc7->regmap, 605 VC7_REG_FOD_INT_CNFG(idx), 606 (u64 *)&val, 607 VC7_REG_FOD_INT_CNFG_COUNT); 608 if (err) { 609 dev_err(&vc7->client->dev, "failed to read FOD%d\n", idx); 610 return err; 611 } 612 613 val = u64_replace_bits(val, 614 vc7->clk_fod[idx].fod_1st_int, 615 VC7_REG_FOD_1ST_INT_MASK); 616 val = u64_replace_bits(val, 617 vc7->clk_fod[idx].fod_2nd_int, 618 VC7_REG_FOD_2ND_INT_MASK); 619 val = u64_replace_bits(val, 620 vc7->clk_fod[idx].fod_frac, 621 VC7_REG_FOD_FRAC_MASK); 622 623 err = regmap_bulk_write(vc7->regmap, 624 VC7_REG_FOD_INT_CNFG(idx), 625 (u64 *)&val, 626 sizeof(u64)); 627 if (err) { 628 dev_err(&vc7->client->dev, "failed to write FOD%d\n", idx); 629 return err; 630 } 631 632 return 0; 633 } 634 635 static int vc7_read_iod(struct vc7_driver_data *vc7, unsigned int idx) 636 { 637 int err; 638 u32 val; 639 640 err = regmap_bulk_read(vc7->regmap, 641 VC7_REG_IOD_INT_CNFG(idx), 642 (u32 *)&val, 643 VC7_REG_IOD_INT_CNFG_COUNT); 644 if (err) { 645 dev_err(&vc7->client->dev, "failed to read IOD%d\n", idx); 646 return err; 647 } 648 649 vc7->clk_iod[idx].iod_int = (val & VC7_REG_IOD_INT_MASK); 650 651 return 0; 652 } 653 654 static int vc7_write_iod(struct vc7_driver_data *vc7, unsigned int idx) 655 { 656 int err; 657 u32 val; 658 659 /* 660 * IOD divider field is atomic and all bits must be written. 661 * The new divider is applied when the MSB of iod_int is written. 662 */ 663 664 err = regmap_bulk_read(vc7->regmap, 665 VC7_REG_IOD_INT_CNFG(idx), 666 (u32 *)&val, 667 VC7_REG_IOD_INT_CNFG_COUNT); 668 if (err) { 669 dev_err(&vc7->client->dev, "failed to read IOD%d\n", idx); 670 return err; 671 } 672 673 val = u32_replace_bits(val, 674 vc7->clk_iod[idx].iod_int, 675 VC7_REG_IOD_INT_MASK); 676 677 err = regmap_bulk_write(vc7->regmap, 678 VC7_REG_IOD_INT_CNFG(idx), 679 (u32 *)&val, 680 sizeof(u32)); 681 if (err) { 682 dev_err(&vc7->client->dev, "failed to write IOD%d\n", idx); 683 return err; 684 } 685 686 return 0; 687 } 688 689 static int vc7_read_output(struct vc7_driver_data *vc7, unsigned int idx) 690 { 691 int err; 692 unsigned int val, out_num; 693 694 out_num = vc7_map_index_to_output(vc7->chip_info->model, idx); 695 err = regmap_read(vc7->regmap, 696 VC7_REG_ODRV_EN(out_num), 697 &val); 698 if (err) { 699 dev_err(&vc7->client->dev, "failed to read ODRV_EN[%d]\n", idx); 700 return err; 701 } 702 703 vc7->clk_out[idx].out_dis = val & VC7_REG_OUT_DIS; 704 705 return 0; 706 } 707 708 static int vc7_write_output(struct vc7_driver_data *vc7, unsigned int idx) 709 { 710 int err; 711 unsigned int out_num; 712 713 out_num = vc7_map_index_to_output(vc7->chip_info->model, idx); 714 err = regmap_write_bits(vc7->regmap, 715 VC7_REG_ODRV_EN(out_num), 716 VC7_REG_OUT_DIS, 717 vc7->clk_out[idx].out_dis); 718 719 if (err) { 720 dev_err(&vc7->client->dev, "failed to write ODRV_EN[%d]\n", idx); 721 return err; 722 } 723 724 return 0; 725 } 726 727 static unsigned long vc7_get_apll_rate(struct vc7_driver_data *vc7) 728 { 729 int err; 730 unsigned long xtal_rate; 731 u64 refin_div, apll_rate; 732 733 xtal_rate = clk_get_rate(vc7->pin_xin); 734 err = vc7_read_apll(vc7); 735 if (err) { 736 dev_err(&vc7->client->dev, "unable to read apll\n"); 737 return err; 738 } 739 740 /* 0 is bypassed, 1 is reserved */ 741 if (vc7->clk_apll.xo_ib_h_div < 2) 742 refin_div = xtal_rate; 743 else 744 refin_div = div64_u64(xtal_rate, vc7->clk_apll.xo_ib_h_div); 745 746 if (vc7->clk_apll.en_doubler) 747 refin_div *= 2; 748 749 /* divider = int + (frac / 2^27) */ 750 apll_rate = (refin_div * vc7->clk_apll.apll_fb_div_int) + 751 ((refin_div * vc7->clk_apll.apll_fb_div_frac) >> VC7_APLL_DENOMINATOR_BITS); 752 753 pr_debug("%s - xo_ib_h_div: %u, apll_fb_div_int: %u, apll_fb_div_frac: %u\n", 754 __func__, vc7->clk_apll.xo_ib_h_div, vc7->clk_apll.apll_fb_div_int, 755 vc7->clk_apll.apll_fb_div_frac); 756 pr_debug("%s - refin_div: %llu, apll rate: %llu\n", 757 __func__, refin_div, apll_rate); 758 759 return apll_rate; 760 } 761 762 static void vc7_calc_iod_divider(unsigned long rate, unsigned long parent_rate, 763 u32 *divider) 764 { 765 *divider = DIV_ROUND_UP(parent_rate, rate); 766 if (*divider < VC7_IOD_MIN_DIVISOR) 767 *divider = VC7_IOD_MIN_DIVISOR; 768 if (*divider > VC7_IOD_MAX_DIVISOR) 769 *divider = VC7_IOD_MAX_DIVISOR; 770 } 771 772 static void vc7_calc_fod_1st_stage(unsigned long rate, unsigned long parent_rate, 773 u32 *div_int, u64 *div_frac) 774 { 775 u64 rem; 776 777 *div_int = (u32)div64_u64_rem(parent_rate, rate, &rem); 778 *div_frac = div64_u64(rem << VC7_FOD_DENOMINATOR_BITS, rate); 779 } 780 781 static unsigned long vc7_calc_fod_1st_stage_rate(unsigned long parent_rate, 782 u32 fod_1st_int, u64 fod_frac) 783 { 784 u64 numer, denom, hi, lo, divisor; 785 786 numer = fod_frac; 787 denom = BIT_ULL(VC7_FOD_DENOMINATOR_BITS); 788 789 if (fod_frac) { 790 vc7_64_mul_64_to_128(parent_rate, denom, &hi, &lo); 791 divisor = ((u64)fod_1st_int * denom) + numer; 792 return vc7_128_div_64_to_64(hi, lo, divisor, NULL); 793 } 794 795 return div64_u64(parent_rate, fod_1st_int); 796 } 797 798 static unsigned long vc7_calc_fod_2nd_stage_rate(unsigned long parent_rate, 799 u32 fod_1st_int, u32 fod_2nd_int, u64 fod_frac) 800 { 801 unsigned long fod_1st_stage_rate; 802 803 fod_1st_stage_rate = vc7_calc_fod_1st_stage_rate(parent_rate, fod_1st_int, fod_frac); 804 805 if (fod_2nd_int < 2) 806 return fod_1st_stage_rate; 807 808 /* 809 * There is a div-by-2 preceding the 2nd stage integer divider 810 * (not shown on block diagram) so the actual 2nd stage integer 811 * divisor is 2 * N. 812 */ 813 return div64_u64(fod_1st_stage_rate >> 1, fod_2nd_int); 814 } 815 816 static void vc7_calc_fod_divider(unsigned long rate, unsigned long parent_rate, 817 u32 *fod_1st_int, u32 *fod_2nd_int, u64 *fod_frac) 818 { 819 unsigned int allow_frac, i, best_frac_i; 820 unsigned long first_stage_rate; 821 822 vc7_calc_fod_1st_stage(rate, parent_rate, fod_1st_int, fod_frac); 823 first_stage_rate = vc7_calc_fod_1st_stage_rate(parent_rate, *fod_1st_int, *fod_frac); 824 825 *fod_2nd_int = 0; 826 827 /* Do we need the second stage integer divider? */ 828 if (first_stage_rate < VC7_FOD_1ST_STAGE_RATE_MIN) { 829 allow_frac = 0; 830 best_frac_i = VC7_FOD_2ND_INT_MIN; 831 832 for (i = VC7_FOD_2ND_INT_MIN; i <= VC7_FOD_2ND_INT_MAX; i++) { 833 /* 834 * 1) There is a div-by-2 preceding the 2nd stage integer divider 835 * (not shown on block diagram) so the actual 2nd stage integer 836 * divisor is 2 * N. 837 * 2) Attempt to find an integer solution first. This means stepping 838 * through each 2nd stage integer and recalculating the 1st stage 839 * until the 1st stage frequency is out of bounds. If no integer 840 * solution is found, use the best fractional solution. 841 */ 842 vc7_calc_fod_1st_stage(parent_rate, rate * 2 * i, fod_1st_int, fod_frac); 843 first_stage_rate = vc7_calc_fod_1st_stage_rate(parent_rate, 844 *fod_1st_int, 845 *fod_frac); 846 847 /* Remember the first viable fractional solution */ 848 if (best_frac_i == VC7_FOD_2ND_INT_MIN && 849 first_stage_rate > VC7_FOD_1ST_STAGE_RATE_MIN) { 850 best_frac_i = i; 851 } 852 853 /* Is the divider viable? Prefer integer solutions over fractional. */ 854 if (*fod_1st_int < VC7_FOD_1ST_INT_MAX && 855 first_stage_rate >= VC7_FOD_1ST_STAGE_RATE_MIN && 856 (allow_frac || *fod_frac == 0)) { 857 *fod_2nd_int = i; 858 break; 859 } 860 861 /* Ran out of divisors or the 1st stage frequency is out of range */ 862 if (i >= VC7_FOD_2ND_INT_MAX || 863 first_stage_rate > VC7_FOD_1ST_STAGE_RATE_MAX) { 864 allow_frac = 1; 865 i = best_frac_i; 866 867 /* Restore the best frac and rerun the loop for the last time */ 868 if (best_frac_i != VC7_FOD_2ND_INT_MIN) 869 i--; 870 871 continue; 872 } 873 } 874 } 875 } 876 877 static unsigned long vc7_fod_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 878 { 879 struct vc7_fod_data *fod = container_of(hw, struct vc7_fod_data, hw); 880 struct vc7_driver_data *vc7 = fod->vc7; 881 int err; 882 unsigned long fod_rate; 883 884 err = vc7_read_fod(vc7, fod->num); 885 if (err) { 886 dev_err(&vc7->client->dev, "error reading registers for %s\n", 887 clk_hw_get_name(hw)); 888 return err; 889 } 890 891 pr_debug("%s - %s: parent_rate: %lu\n", __func__, clk_hw_get_name(hw), parent_rate); 892 893 fod_rate = vc7_calc_fod_2nd_stage_rate(parent_rate, fod->fod_1st_int, 894 fod->fod_2nd_int, fod->fod_frac); 895 896 pr_debug("%s - %s: fod_1st_int: %u, fod_2nd_int: %u, fod_frac: %llu\n", 897 __func__, clk_hw_get_name(hw), 898 fod->fod_1st_int, fod->fod_2nd_int, fod->fod_frac); 899 pr_debug("%s - %s rate: %lu\n", __func__, clk_hw_get_name(hw), fod_rate); 900 901 return fod_rate; 902 } 903 904 static long vc7_fod_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) 905 { 906 struct vc7_fod_data *fod = container_of(hw, struct vc7_fod_data, hw); 907 unsigned long fod_rate; 908 909 pr_debug("%s - %s: requested rate: %lu, parent_rate: %lu\n", 910 __func__, clk_hw_get_name(hw), rate, *parent_rate); 911 912 vc7_calc_fod_divider(rate, *parent_rate, 913 &fod->fod_1st_int, &fod->fod_2nd_int, &fod->fod_frac); 914 fod_rate = vc7_calc_fod_2nd_stage_rate(*parent_rate, fod->fod_1st_int, 915 fod->fod_2nd_int, fod->fod_frac); 916 917 pr_debug("%s - %s: fod_1st_int: %u, fod_2nd_int: %u, fod_frac: %llu\n", 918 __func__, clk_hw_get_name(hw), 919 fod->fod_1st_int, fod->fod_2nd_int, fod->fod_frac); 920 pr_debug("%s - %s rate: %lu\n", __func__, clk_hw_get_name(hw), fod_rate); 921 922 return fod_rate; 923 } 924 925 static int vc7_fod_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) 926 { 927 struct vc7_fod_data *fod = container_of(hw, struct vc7_fod_data, hw); 928 struct vc7_driver_data *vc7 = fod->vc7; 929 unsigned long fod_rate; 930 931 pr_debug("%s - %s: rate: %lu, parent_rate: %lu\n", 932 __func__, clk_hw_get_name(hw), rate, parent_rate); 933 934 if (rate < VC7_FOD_RATE_MIN || rate > VC7_FOD_RATE_MAX) { 935 dev_err(&vc7->client->dev, 936 "requested frequency %lu Hz for %s is out of range\n", 937 rate, clk_hw_get_name(hw)); 938 return -EINVAL; 939 } 940 941 vc7_write_fod(vc7, fod->num); 942 943 fod_rate = vc7_calc_fod_2nd_stage_rate(parent_rate, fod->fod_1st_int, 944 fod->fod_2nd_int, fod->fod_frac); 945 946 pr_debug("%s - %s: fod_1st_int: %u, fod_2nd_int: %u, fod_frac: %llu\n", 947 __func__, clk_hw_get_name(hw), 948 fod->fod_1st_int, fod->fod_2nd_int, fod->fod_frac); 949 pr_debug("%s - %s rate: %lu\n", __func__, clk_hw_get_name(hw), fod_rate); 950 951 return 0; 952 } 953 954 static const struct clk_ops vc7_fod_ops = { 955 .recalc_rate = vc7_fod_recalc_rate, 956 .round_rate = vc7_fod_round_rate, 957 .set_rate = vc7_fod_set_rate, 958 }; 959 960 static unsigned long vc7_iod_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 961 { 962 struct vc7_iod_data *iod = container_of(hw, struct vc7_iod_data, hw); 963 struct vc7_driver_data *vc7 = iod->vc7; 964 int err; 965 unsigned long iod_rate; 966 967 err = vc7_read_iod(vc7, iod->num); 968 if (err) { 969 dev_err(&vc7->client->dev, "error reading registers for %s\n", 970 clk_hw_get_name(hw)); 971 return err; 972 } 973 974 iod_rate = div64_u64(parent_rate, iod->iod_int); 975 976 pr_debug("%s - %s: iod_int: %u\n", __func__, clk_hw_get_name(hw), iod->iod_int); 977 pr_debug("%s - %s rate: %lu\n", __func__, clk_hw_get_name(hw), iod_rate); 978 979 return iod_rate; 980 } 981 982 static long vc7_iod_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) 983 { 984 struct vc7_iod_data *iod = container_of(hw, struct vc7_iod_data, hw); 985 unsigned long iod_rate; 986 987 pr_debug("%s - %s: requested rate: %lu, parent_rate: %lu\n", 988 __func__, clk_hw_get_name(hw), rate, *parent_rate); 989 990 vc7_calc_iod_divider(rate, *parent_rate, &iod->iod_int); 991 iod_rate = div64_u64(*parent_rate, iod->iod_int); 992 993 pr_debug("%s - %s: iod_int: %u\n", __func__, clk_hw_get_name(hw), iod->iod_int); 994 pr_debug("%s - %s rate: %ld\n", __func__, clk_hw_get_name(hw), iod_rate); 995 996 return iod_rate; 997 } 998 999 static int vc7_iod_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) 1000 { 1001 struct vc7_iod_data *iod = container_of(hw, struct vc7_iod_data, hw); 1002 struct vc7_driver_data *vc7 = iod->vc7; 1003 unsigned long iod_rate; 1004 1005 pr_debug("%s - %s: rate: %lu, parent_rate: %lu\n", 1006 __func__, clk_hw_get_name(hw), rate, parent_rate); 1007 1008 if (rate < VC7_IOD_RATE_MIN || rate > VC7_IOD_RATE_MAX) { 1009 dev_err(&vc7->client->dev, 1010 "requested frequency %lu Hz for %s is out of range\n", 1011 rate, clk_hw_get_name(hw)); 1012 return -EINVAL; 1013 } 1014 1015 vc7_write_iod(vc7, iod->num); 1016 1017 iod_rate = div64_u64(parent_rate, iod->iod_int); 1018 1019 pr_debug("%s - %s: iod_int: %u\n", __func__, clk_hw_get_name(hw), iod->iod_int); 1020 pr_debug("%s - %s rate: %ld\n", __func__, clk_hw_get_name(hw), iod_rate); 1021 1022 return 0; 1023 } 1024 1025 static const struct clk_ops vc7_iod_ops = { 1026 .recalc_rate = vc7_iod_recalc_rate, 1027 .round_rate = vc7_iod_round_rate, 1028 .set_rate = vc7_iod_set_rate, 1029 }; 1030 1031 static int vc7_clk_out_prepare(struct clk_hw *hw) 1032 { 1033 struct vc7_out_data *out = container_of(hw, struct vc7_out_data, hw); 1034 struct vc7_driver_data *vc7 = out->vc7; 1035 int err; 1036 1037 out->out_dis = 0; 1038 1039 err = vc7_write_output(vc7, out->num); 1040 if (err) { 1041 dev_err(&vc7->client->dev, "error writing registers for %s\n", 1042 clk_hw_get_name(hw)); 1043 return err; 1044 } 1045 1046 pr_debug("%s - %s: clk prepared\n", __func__, clk_hw_get_name(hw)); 1047 1048 return 0; 1049 } 1050 1051 static void vc7_clk_out_unprepare(struct clk_hw *hw) 1052 { 1053 struct vc7_out_data *out = container_of(hw, struct vc7_out_data, hw); 1054 struct vc7_driver_data *vc7 = out->vc7; 1055 int err; 1056 1057 out->out_dis = 1; 1058 1059 err = vc7_write_output(vc7, out->num); 1060 if (err) { 1061 dev_err(&vc7->client->dev, "error writing registers for %s\n", 1062 clk_hw_get_name(hw)); 1063 return; 1064 } 1065 1066 pr_debug("%s - %s: clk unprepared\n", __func__, clk_hw_get_name(hw)); 1067 } 1068 1069 static int vc7_clk_out_is_enabled(struct clk_hw *hw) 1070 { 1071 struct vc7_out_data *out = container_of(hw, struct vc7_out_data, hw); 1072 struct vc7_driver_data *vc7 = out->vc7; 1073 int err, is_enabled; 1074 1075 err = vc7_read_output(vc7, out->num); 1076 if (err) { 1077 dev_err(&vc7->client->dev, "error reading registers for %s\n", 1078 clk_hw_get_name(hw)); 1079 return err; 1080 } 1081 1082 is_enabled = !out->out_dis; 1083 1084 pr_debug("%s - %s: is_enabled=%d\n", __func__, clk_hw_get_name(hw), is_enabled); 1085 1086 return is_enabled; 1087 } 1088 1089 static const struct clk_ops vc7_clk_out_ops = { 1090 .prepare = vc7_clk_out_prepare, 1091 .unprepare = vc7_clk_out_unprepare, 1092 .is_enabled = vc7_clk_out_is_enabled, 1093 }; 1094 1095 static int vc7_probe(struct i2c_client *client) 1096 { 1097 struct vc7_driver_data *vc7; 1098 struct clk_init_data clk_init; 1099 struct vc7_bank_src_map bank_src_map; 1100 const char *node_name, *apll_name; 1101 const char *parent_names[1]; 1102 unsigned int i, val, bank_idx, out_num; 1103 unsigned long apll_rate; 1104 int ret; 1105 1106 vc7 = devm_kzalloc(&client->dev, sizeof(*vc7), GFP_KERNEL); 1107 if (!vc7) 1108 return -ENOMEM; 1109 1110 i2c_set_clientdata(client, vc7); 1111 vc7->client = client; 1112 vc7->chip_info = device_get_match_data(&client->dev); 1113 1114 vc7->pin_xin = devm_clk_get(&client->dev, "xin"); 1115 if (PTR_ERR(vc7->pin_xin) == -EPROBE_DEFER) { 1116 return dev_err_probe(&client->dev, -EPROBE_DEFER, 1117 "xin not specified\n"); 1118 } 1119 1120 vc7->regmap = devm_regmap_init_i2c(client, &vc7_regmap_config); 1121 if (IS_ERR(vc7->regmap)) { 1122 return dev_err_probe(&client->dev, PTR_ERR(vc7->regmap), 1123 "failed to allocate register map\n"); 1124 } 1125 1126 if (of_property_read_string(client->dev.of_node, "clock-output-names", 1127 &node_name)) 1128 node_name = client->dev.of_node->name; 1129 1130 /* Register APLL */ 1131 apll_rate = vc7_get_apll_rate(vc7); 1132 apll_name = kasprintf(GFP_KERNEL, "%s_apll", node_name); 1133 vc7->clk_apll.clk = clk_register_fixed_rate(&client->dev, apll_name, 1134 __clk_get_name(vc7->pin_xin), 1135 0, apll_rate); 1136 kfree(apll_name); /* ccf made a copy of the name */ 1137 if (IS_ERR(vc7->clk_apll.clk)) { 1138 return dev_err_probe(&client->dev, PTR_ERR(vc7->clk_apll.clk), 1139 "failed to register apll\n"); 1140 } 1141 1142 /* Register FODs */ 1143 for (i = 0; i < VC7_NUM_FOD; i++) { 1144 memset(&clk_init, 0, sizeof(clk_init)); 1145 clk_init.name = kasprintf(GFP_KERNEL, "%s_fod%d", node_name, i); 1146 clk_init.ops = &vc7_fod_ops; 1147 clk_init.parent_names = parent_names; 1148 parent_names[0] = __clk_get_name(vc7->clk_apll.clk); 1149 clk_init.num_parents = 1; 1150 vc7->clk_fod[i].num = i; 1151 vc7->clk_fod[i].vc7 = vc7; 1152 vc7->clk_fod[i].hw.init = &clk_init; 1153 ret = devm_clk_hw_register(&client->dev, &vc7->clk_fod[i].hw); 1154 if (ret) 1155 goto err_clk_register; 1156 kfree(clk_init.name); /* ccf made a copy of the name */ 1157 } 1158 1159 /* Register IODs */ 1160 for (i = 0; i < VC7_NUM_IOD; i++) { 1161 memset(&clk_init, 0, sizeof(clk_init)); 1162 clk_init.name = kasprintf(GFP_KERNEL, "%s_iod%d", node_name, i); 1163 clk_init.ops = &vc7_iod_ops; 1164 clk_init.parent_names = parent_names; 1165 parent_names[0] = __clk_get_name(vc7->clk_apll.clk); 1166 clk_init.num_parents = 1; 1167 vc7->clk_iod[i].num = i; 1168 vc7->clk_iod[i].vc7 = vc7; 1169 vc7->clk_iod[i].hw.init = &clk_init; 1170 ret = devm_clk_hw_register(&client->dev, &vc7->clk_iod[i].hw); 1171 if (ret) 1172 goto err_clk_register; 1173 kfree(clk_init.name); /* ccf made a copy of the name */ 1174 } 1175 1176 /* Register outputs */ 1177 for (i = 0; i < vc7->chip_info->num_outputs; i++) { 1178 out_num = vc7_map_index_to_output(vc7->chip_info->model, i); 1179 1180 /* 1181 * This driver does not support remapping FOD/IOD to banks. 1182 * The device state is read and the driver is setup to match 1183 * the device's existing mapping. 1184 */ 1185 bank_idx = output_bank_mapping[out_num]; 1186 1187 regmap_read(vc7->regmap, VC7_REG_OUT_BANK_CNFG(bank_idx), &val); 1188 val &= VC7_REG_OUTPUT_BANK_SRC_MASK; 1189 1190 memset(&bank_src_map, 0, sizeof(bank_src_map)); 1191 ret = vc7_get_bank_clk(vc7, bank_idx, val, &bank_src_map); 1192 if (ret) { 1193 dev_err_probe(&client->dev, ret, 1194 "unable to register output %d\n", i); 1195 return ret; 1196 } 1197 1198 switch (bank_src_map.type) { 1199 case VC7_FOD: 1200 parent_names[0] = clk_hw_get_name(&bank_src_map.src.fod->hw); 1201 break; 1202 case VC7_IOD: 1203 parent_names[0] = clk_hw_get_name(&bank_src_map.src.iod->hw); 1204 break; 1205 } 1206 1207 memset(&clk_init, 0, sizeof(clk_init)); 1208 clk_init.name = kasprintf(GFP_KERNEL, "%s_out%d", node_name, i); 1209 clk_init.ops = &vc7_clk_out_ops; 1210 clk_init.flags = CLK_SET_RATE_PARENT; 1211 clk_init.parent_names = parent_names; 1212 clk_init.num_parents = 1; 1213 vc7->clk_out[i].num = i; 1214 vc7->clk_out[i].vc7 = vc7; 1215 vc7->clk_out[i].hw.init = &clk_init; 1216 ret = devm_clk_hw_register(&client->dev, &vc7->clk_out[i].hw); 1217 if (ret) 1218 goto err_clk_register; 1219 kfree(clk_init.name); /* ccf made a copy of the name */ 1220 } 1221 1222 ret = of_clk_add_hw_provider(client->dev.of_node, vc7_of_clk_get, vc7); 1223 if (ret) { 1224 dev_err_probe(&client->dev, ret, "unable to add clk provider\n"); 1225 goto err_clk; 1226 } 1227 1228 return ret; 1229 1230 err_clk_register: 1231 dev_err_probe(&client->dev, ret, 1232 "unable to register %s\n", clk_init.name); 1233 kfree(clk_init.name); /* ccf made a copy of the name */ 1234 err_clk: 1235 clk_unregister_fixed_rate(vc7->clk_apll.clk); 1236 return ret; 1237 } 1238 1239 static void vc7_remove(struct i2c_client *client) 1240 { 1241 struct vc7_driver_data *vc7 = i2c_get_clientdata(client); 1242 1243 of_clk_del_provider(client->dev.of_node); 1244 clk_unregister_fixed_rate(vc7->clk_apll.clk); 1245 } 1246 1247 static bool vc7_volatile_reg(struct device *dev, unsigned int reg) 1248 { 1249 if (reg == VC7_PAGE_ADDR) 1250 return false; 1251 1252 return true; 1253 } 1254 1255 static const struct vc7_chip_info vc7_rc21008a_info = { 1256 .model = VC7_RC21008A, 1257 .num_banks = 6, 1258 .num_outputs = 8, 1259 }; 1260 1261 static struct regmap_range_cfg vc7_range_cfg[] = { 1262 { 1263 .range_min = 0, 1264 .range_max = VC7_MAX_REG, 1265 .selector_reg = VC7_PAGE_ADDR, 1266 .selector_mask = 0xFF, 1267 .selector_shift = 0, 1268 .window_start = 0, 1269 .window_len = VC7_PAGE_WINDOW, 1270 }}; 1271 1272 static const struct regmap_config vc7_regmap_config = { 1273 .reg_bits = 8, 1274 .val_bits = 8, 1275 .max_register = VC7_MAX_REG, 1276 .ranges = vc7_range_cfg, 1277 .num_ranges = ARRAY_SIZE(vc7_range_cfg), 1278 .volatile_reg = vc7_volatile_reg, 1279 .cache_type = REGCACHE_RBTREE, 1280 .can_multi_write = true, 1281 .reg_format_endian = REGMAP_ENDIAN_LITTLE, 1282 .val_format_endian = REGMAP_ENDIAN_LITTLE, 1283 }; 1284 1285 static const struct i2c_device_id vc7_i2c_id[] = { 1286 { "rc21008a", .driver_data = (kernel_ulong_t)&vc7_rc21008a_info }, 1287 {} 1288 }; 1289 MODULE_DEVICE_TABLE(i2c, vc7_i2c_id); 1290 1291 static const struct of_device_id vc7_of_match[] = { 1292 { .compatible = "renesas,rc21008a", .data = &vc7_rc21008a_info }, 1293 {} 1294 }; 1295 MODULE_DEVICE_TABLE(of, vc7_of_match); 1296 1297 static struct i2c_driver vc7_i2c_driver = { 1298 .driver = { 1299 .name = "vc7", 1300 .of_match_table = vc7_of_match, 1301 }, 1302 .probe = vc7_probe, 1303 .remove = vc7_remove, 1304 .id_table = vc7_i2c_id, 1305 }; 1306 module_i2c_driver(vc7_i2c_driver); 1307 1308 MODULE_LICENSE("GPL"); 1309 MODULE_AUTHOR("Alex Helms <alexander.helms.jy@renesas.com"); 1310 MODULE_DESCRIPTION("Renesas Versaclock7 common clock framework driver"); 1311