18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Driver for TI Multi PLL CDCE913/925/937/949 clock synthesizer 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * This driver always connects the Y1 to the input clock, Y2/Y3 to PLL1, 58c2ecf20Sopenharmony_ci * Y4/Y5 to PLL2, and so on. PLL frequency is set on a first-come-first-serve 68c2ecf20Sopenharmony_ci * basis. Clients can directly request any frequency that the chip can 78c2ecf20Sopenharmony_ci * deliver using the standard clk framework. In addition, the device can 88c2ecf20Sopenharmony_ci * be configured and activated via the devicetree. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Copyright (C) 2014, Topic Embedded Products 118c2ecf20Sopenharmony_ci * Licenced under GPL 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci#include <linux/clk.h> 148c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 158c2ecf20Sopenharmony_ci#include <linux/delay.h> 168c2ecf20Sopenharmony_ci#include <linux/module.h> 178c2ecf20Sopenharmony_ci#include <linux/i2c.h> 188c2ecf20Sopenharmony_ci#include <linux/regmap.h> 198c2ecf20Sopenharmony_ci#include <linux/regulator/consumer.h> 208c2ecf20Sopenharmony_ci#include <linux/slab.h> 218c2ecf20Sopenharmony_ci#include <linux/gcd.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci/* Each chip has different number of PLLs and outputs, for example: 248c2ecf20Sopenharmony_ci * The CECE925 has 2 PLLs which can be routed through dividers to 5 outputs. 258c2ecf20Sopenharmony_ci * Model this as 2 PLL clocks which are parents to the outputs. 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cienum { 298c2ecf20Sopenharmony_ci CDCE913, 308c2ecf20Sopenharmony_ci CDCE925, 318c2ecf20Sopenharmony_ci CDCE937, 328c2ecf20Sopenharmony_ci CDCE949, 338c2ecf20Sopenharmony_ci}; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistruct clk_cdce925_chip_info { 368c2ecf20Sopenharmony_ci int num_plls; 378c2ecf20Sopenharmony_ci int num_outputs; 388c2ecf20Sopenharmony_ci}; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic const struct clk_cdce925_chip_info clk_cdce925_chip_info_tbl[] = { 418c2ecf20Sopenharmony_ci [CDCE913] = { .num_plls = 1, .num_outputs = 3 }, 428c2ecf20Sopenharmony_ci [CDCE925] = { .num_plls = 2, .num_outputs = 5 }, 438c2ecf20Sopenharmony_ci [CDCE937] = { .num_plls = 3, .num_outputs = 7 }, 448c2ecf20Sopenharmony_ci [CDCE949] = { .num_plls = 4, .num_outputs = 9 }, 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define MAX_NUMBER_OF_PLLS 4 488c2ecf20Sopenharmony_ci#define MAX_NUMBER_OF_OUTPUTS 9 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#define CDCE925_REG_GLOBAL1 0x01 518c2ecf20Sopenharmony_ci#define CDCE925_REG_Y1SPIPDIVH 0x02 528c2ecf20Sopenharmony_ci#define CDCE925_REG_PDIVL 0x03 538c2ecf20Sopenharmony_ci#define CDCE925_REG_XCSEL 0x05 548c2ecf20Sopenharmony_ci/* PLL parameters start at 0x10, steps of 0x10 */ 558c2ecf20Sopenharmony_ci#define CDCE925_OFFSET_PLL 0x10 568c2ecf20Sopenharmony_ci/* Add CDCE925_OFFSET_PLL * (pll) to these registers before sending */ 578c2ecf20Sopenharmony_ci#define CDCE925_PLL_MUX_OUTPUTS 0x14 588c2ecf20Sopenharmony_ci#define CDCE925_PLL_MULDIV 0x18 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#define CDCE925_PLL_FREQUENCY_MIN 80000000ul 618c2ecf20Sopenharmony_ci#define CDCE925_PLL_FREQUENCY_MAX 230000000ul 628c2ecf20Sopenharmony_cistruct clk_cdce925_chip; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistruct clk_cdce925_output { 658c2ecf20Sopenharmony_ci struct clk_hw hw; 668c2ecf20Sopenharmony_ci struct clk_cdce925_chip *chip; 678c2ecf20Sopenharmony_ci u8 index; 688c2ecf20Sopenharmony_ci u16 pdiv; /* 1..127 for Y2-Y9; 1..1023 for Y1 */ 698c2ecf20Sopenharmony_ci}; 708c2ecf20Sopenharmony_ci#define to_clk_cdce925_output(_hw) \ 718c2ecf20Sopenharmony_ci container_of(_hw, struct clk_cdce925_output, hw) 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistruct clk_cdce925_pll { 748c2ecf20Sopenharmony_ci struct clk_hw hw; 758c2ecf20Sopenharmony_ci struct clk_cdce925_chip *chip; 768c2ecf20Sopenharmony_ci u8 index; 778c2ecf20Sopenharmony_ci u16 m; /* 1..511 */ 788c2ecf20Sopenharmony_ci u16 n; /* 1..4095 */ 798c2ecf20Sopenharmony_ci}; 808c2ecf20Sopenharmony_ci#define to_clk_cdce925_pll(_hw) container_of(_hw, struct clk_cdce925_pll, hw) 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistruct clk_cdce925_chip { 838c2ecf20Sopenharmony_ci struct regmap *regmap; 848c2ecf20Sopenharmony_ci struct i2c_client *i2c_client; 858c2ecf20Sopenharmony_ci const struct clk_cdce925_chip_info *chip_info; 868c2ecf20Sopenharmony_ci struct clk_cdce925_pll pll[MAX_NUMBER_OF_PLLS]; 878c2ecf20Sopenharmony_ci struct clk_cdce925_output clk[MAX_NUMBER_OF_OUTPUTS]; 888c2ecf20Sopenharmony_ci}; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic unsigned long cdce925_pll_calculate_rate(unsigned long parent_rate, 938c2ecf20Sopenharmony_ci u16 n, u16 m) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci if ((!m || !n) || (m == n)) 968c2ecf20Sopenharmony_ci return parent_rate; /* In bypass mode runs at same frequency */ 978c2ecf20Sopenharmony_ci return mult_frac(parent_rate, (unsigned long)n, (unsigned long)m); 988c2ecf20Sopenharmony_ci} 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistatic unsigned long cdce925_pll_recalc_rate(struct clk_hw *hw, 1018c2ecf20Sopenharmony_ci unsigned long parent_rate) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci /* Output frequency of PLL is Fout = (Fin/Pdiv)*(N/M) */ 1048c2ecf20Sopenharmony_ci struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci return cdce925_pll_calculate_rate(parent_rate, data->n, data->m); 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic void cdce925_pll_find_rate(unsigned long rate, 1108c2ecf20Sopenharmony_ci unsigned long parent_rate, u16 *n, u16 *m) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci unsigned long un; 1138c2ecf20Sopenharmony_ci unsigned long um; 1148c2ecf20Sopenharmony_ci unsigned long g; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci if (rate <= parent_rate) { 1178c2ecf20Sopenharmony_ci /* Can always deliver parent_rate in bypass mode */ 1188c2ecf20Sopenharmony_ci rate = parent_rate; 1198c2ecf20Sopenharmony_ci *n = 0; 1208c2ecf20Sopenharmony_ci *m = 0; 1218c2ecf20Sopenharmony_ci } else { 1228c2ecf20Sopenharmony_ci /* In PLL mode, need to apply min/max range */ 1238c2ecf20Sopenharmony_ci if (rate < CDCE925_PLL_FREQUENCY_MIN) 1248c2ecf20Sopenharmony_ci rate = CDCE925_PLL_FREQUENCY_MIN; 1258c2ecf20Sopenharmony_ci else if (rate > CDCE925_PLL_FREQUENCY_MAX) 1268c2ecf20Sopenharmony_ci rate = CDCE925_PLL_FREQUENCY_MAX; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci g = gcd(rate, parent_rate); 1298c2ecf20Sopenharmony_ci um = parent_rate / g; 1308c2ecf20Sopenharmony_ci un = rate / g; 1318c2ecf20Sopenharmony_ci /* When outside hw range, reduce to fit (rounding errors) */ 1328c2ecf20Sopenharmony_ci while ((un > 4095) || (um > 511)) { 1338c2ecf20Sopenharmony_ci un >>= 1; 1348c2ecf20Sopenharmony_ci um >>= 1; 1358c2ecf20Sopenharmony_ci } 1368c2ecf20Sopenharmony_ci if (un == 0) 1378c2ecf20Sopenharmony_ci un = 1; 1388c2ecf20Sopenharmony_ci if (um == 0) 1398c2ecf20Sopenharmony_ci um = 1; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci *n = un; 1428c2ecf20Sopenharmony_ci *m = um; 1438c2ecf20Sopenharmony_ci } 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic long cdce925_pll_round_rate(struct clk_hw *hw, unsigned long rate, 1478c2ecf20Sopenharmony_ci unsigned long *parent_rate) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci u16 n, m; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci cdce925_pll_find_rate(rate, *parent_rate, &n, &m); 1528c2ecf20Sopenharmony_ci return (long)cdce925_pll_calculate_rate(*parent_rate, n, m); 1538c2ecf20Sopenharmony_ci} 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_cistatic int cdce925_pll_set_rate(struct clk_hw *hw, unsigned long rate, 1568c2ecf20Sopenharmony_ci unsigned long parent_rate) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci if (!rate || (rate == parent_rate)) { 1618c2ecf20Sopenharmony_ci data->m = 0; /* Bypass mode */ 1628c2ecf20Sopenharmony_ci data->n = 0; 1638c2ecf20Sopenharmony_ci return 0; 1648c2ecf20Sopenharmony_ci } 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci if ((rate < CDCE925_PLL_FREQUENCY_MIN) || 1678c2ecf20Sopenharmony_ci (rate > CDCE925_PLL_FREQUENCY_MAX)) { 1688c2ecf20Sopenharmony_ci pr_debug("%s: rate %lu outside PLL range.\n", __func__, rate); 1698c2ecf20Sopenharmony_ci return -EINVAL; 1708c2ecf20Sopenharmony_ci } 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci if (rate < parent_rate) { 1738c2ecf20Sopenharmony_ci pr_debug("%s: rate %lu less than parent rate %lu.\n", __func__, 1748c2ecf20Sopenharmony_ci rate, parent_rate); 1758c2ecf20Sopenharmony_ci return -EINVAL; 1768c2ecf20Sopenharmony_ci } 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci cdce925_pll_find_rate(rate, parent_rate, &data->n, &data->m); 1798c2ecf20Sopenharmony_ci return 0; 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci/* calculate p = max(0, 4 - int(log2 (n/m))) */ 1848c2ecf20Sopenharmony_cistatic u8 cdce925_pll_calc_p(u16 n, u16 m) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci u8 p; 1878c2ecf20Sopenharmony_ci u16 r = n / m; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci if (r >= 16) 1908c2ecf20Sopenharmony_ci return 0; 1918c2ecf20Sopenharmony_ci p = 4; 1928c2ecf20Sopenharmony_ci while (r > 1) { 1938c2ecf20Sopenharmony_ci r >>= 1; 1948c2ecf20Sopenharmony_ci --p; 1958c2ecf20Sopenharmony_ci } 1968c2ecf20Sopenharmony_ci return p; 1978c2ecf20Sopenharmony_ci} 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci/* Returns VCO range bits for VCO1_0_RANGE */ 2008c2ecf20Sopenharmony_cistatic u8 cdce925_pll_calc_range_bits(struct clk_hw *hw, u16 n, u16 m) 2018c2ecf20Sopenharmony_ci{ 2028c2ecf20Sopenharmony_ci struct clk *parent = clk_get_parent(hw->clk); 2038c2ecf20Sopenharmony_ci unsigned long rate = clk_get_rate(parent); 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci rate = mult_frac(rate, (unsigned long)n, (unsigned long)m); 2068c2ecf20Sopenharmony_ci if (rate >= 175000000) 2078c2ecf20Sopenharmony_ci return 0x3; 2088c2ecf20Sopenharmony_ci if (rate >= 150000000) 2098c2ecf20Sopenharmony_ci return 0x02; 2108c2ecf20Sopenharmony_ci if (rate >= 125000000) 2118c2ecf20Sopenharmony_ci return 0x01; 2128c2ecf20Sopenharmony_ci return 0x00; 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci/* I2C clock, hence everything must happen in (un)prepare because this 2168c2ecf20Sopenharmony_ci * may sleep */ 2178c2ecf20Sopenharmony_cistatic int cdce925_pll_prepare(struct clk_hw *hw) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw); 2208c2ecf20Sopenharmony_ci u16 n = data->n; 2218c2ecf20Sopenharmony_ci u16 m = data->m; 2228c2ecf20Sopenharmony_ci u16 r; 2238c2ecf20Sopenharmony_ci u8 q; 2248c2ecf20Sopenharmony_ci u8 p; 2258c2ecf20Sopenharmony_ci u16 nn; 2268c2ecf20Sopenharmony_ci u8 pll[4]; /* Bits are spread out over 4 byte registers */ 2278c2ecf20Sopenharmony_ci u8 reg_ofs = data->index * CDCE925_OFFSET_PLL; 2288c2ecf20Sopenharmony_ci unsigned i; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci if ((!m || !n) || (m == n)) { 2318c2ecf20Sopenharmony_ci /* Set PLL mux to bypass mode, leave the rest as is */ 2328c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 2338c2ecf20Sopenharmony_ci reg_ofs + CDCE925_PLL_MUX_OUTPUTS, 0x80, 0x80); 2348c2ecf20Sopenharmony_ci } else { 2358c2ecf20Sopenharmony_ci /* According to data sheet: */ 2368c2ecf20Sopenharmony_ci /* p = max(0, 4 - int(log2 (n/m))) */ 2378c2ecf20Sopenharmony_ci p = cdce925_pll_calc_p(n, m); 2388c2ecf20Sopenharmony_ci /* nn = n * 2^p */ 2398c2ecf20Sopenharmony_ci nn = n * BIT(p); 2408c2ecf20Sopenharmony_ci /* q = int(nn/m) */ 2418c2ecf20Sopenharmony_ci q = nn / m; 2428c2ecf20Sopenharmony_ci if ((q < 16) || (q > 63)) { 2438c2ecf20Sopenharmony_ci pr_debug("%s invalid q=%d\n", __func__, q); 2448c2ecf20Sopenharmony_ci return -EINVAL; 2458c2ecf20Sopenharmony_ci } 2468c2ecf20Sopenharmony_ci r = nn - (m*q); 2478c2ecf20Sopenharmony_ci if (r > 511) { 2488c2ecf20Sopenharmony_ci pr_debug("%s invalid r=%d\n", __func__, r); 2498c2ecf20Sopenharmony_ci return -EINVAL; 2508c2ecf20Sopenharmony_ci } 2518c2ecf20Sopenharmony_ci pr_debug("%s n=%d m=%d p=%d q=%d r=%d\n", __func__, 2528c2ecf20Sopenharmony_ci n, m, p, q, r); 2538c2ecf20Sopenharmony_ci /* encode into register bits */ 2548c2ecf20Sopenharmony_ci pll[0] = n >> 4; 2558c2ecf20Sopenharmony_ci pll[1] = ((n & 0x0F) << 4) | ((r >> 5) & 0x0F); 2568c2ecf20Sopenharmony_ci pll[2] = ((r & 0x1F) << 3) | ((q >> 3) & 0x07); 2578c2ecf20Sopenharmony_ci pll[3] = ((q & 0x07) << 5) | (p << 2) | 2588c2ecf20Sopenharmony_ci cdce925_pll_calc_range_bits(hw, n, m); 2598c2ecf20Sopenharmony_ci /* Write to registers */ 2608c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(pll); ++i) 2618c2ecf20Sopenharmony_ci regmap_write(data->chip->regmap, 2628c2ecf20Sopenharmony_ci reg_ofs + CDCE925_PLL_MULDIV + i, pll[i]); 2638c2ecf20Sopenharmony_ci /* Enable PLL */ 2648c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 2658c2ecf20Sopenharmony_ci reg_ofs + CDCE925_PLL_MUX_OUTPUTS, 0x80, 0x00); 2668c2ecf20Sopenharmony_ci } 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci return 0; 2698c2ecf20Sopenharmony_ci} 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_cistatic void cdce925_pll_unprepare(struct clk_hw *hw) 2728c2ecf20Sopenharmony_ci{ 2738c2ecf20Sopenharmony_ci struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw); 2748c2ecf20Sopenharmony_ci u8 reg_ofs = data->index * CDCE925_OFFSET_PLL; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 2778c2ecf20Sopenharmony_ci reg_ofs + CDCE925_PLL_MUX_OUTPUTS, 0x80, 0x80); 2788c2ecf20Sopenharmony_ci} 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_cistatic const struct clk_ops cdce925_pll_ops = { 2818c2ecf20Sopenharmony_ci .prepare = cdce925_pll_prepare, 2828c2ecf20Sopenharmony_ci .unprepare = cdce925_pll_unprepare, 2838c2ecf20Sopenharmony_ci .recalc_rate = cdce925_pll_recalc_rate, 2848c2ecf20Sopenharmony_ci .round_rate = cdce925_pll_round_rate, 2858c2ecf20Sopenharmony_ci .set_rate = cdce925_pll_set_rate, 2868c2ecf20Sopenharmony_ci}; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cistatic void cdce925_clk_set_pdiv(struct clk_cdce925_output *data, u16 pdiv) 2908c2ecf20Sopenharmony_ci{ 2918c2ecf20Sopenharmony_ci switch (data->index) { 2928c2ecf20Sopenharmony_ci case 0: 2938c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 2948c2ecf20Sopenharmony_ci CDCE925_REG_Y1SPIPDIVH, 2958c2ecf20Sopenharmony_ci 0x03, (pdiv >> 8) & 0x03); 2968c2ecf20Sopenharmony_ci regmap_write(data->chip->regmap, 0x03, pdiv & 0xFF); 2978c2ecf20Sopenharmony_ci break; 2988c2ecf20Sopenharmony_ci case 1: 2998c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x16, 0x7F, pdiv); 3008c2ecf20Sopenharmony_ci break; 3018c2ecf20Sopenharmony_ci case 2: 3028c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x17, 0x7F, pdiv); 3038c2ecf20Sopenharmony_ci break; 3048c2ecf20Sopenharmony_ci case 3: 3058c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x26, 0x7F, pdiv); 3068c2ecf20Sopenharmony_ci break; 3078c2ecf20Sopenharmony_ci case 4: 3088c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x27, 0x7F, pdiv); 3098c2ecf20Sopenharmony_ci break; 3108c2ecf20Sopenharmony_ci case 5: 3118c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x36, 0x7F, pdiv); 3128c2ecf20Sopenharmony_ci break; 3138c2ecf20Sopenharmony_ci case 6: 3148c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x37, 0x7F, pdiv); 3158c2ecf20Sopenharmony_ci break; 3168c2ecf20Sopenharmony_ci case 7: 3178c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x46, 0x7F, pdiv); 3188c2ecf20Sopenharmony_ci break; 3198c2ecf20Sopenharmony_ci case 8: 3208c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x47, 0x7F, pdiv); 3218c2ecf20Sopenharmony_ci break; 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci} 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_cistatic void cdce925_clk_activate(struct clk_cdce925_output *data) 3268c2ecf20Sopenharmony_ci{ 3278c2ecf20Sopenharmony_ci switch (data->index) { 3288c2ecf20Sopenharmony_ci case 0: 3298c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 3308c2ecf20Sopenharmony_ci CDCE925_REG_Y1SPIPDIVH, 0x0c, 0x0c); 3318c2ecf20Sopenharmony_ci break; 3328c2ecf20Sopenharmony_ci case 1: 3338c2ecf20Sopenharmony_ci case 2: 3348c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x14, 0x03, 0x03); 3358c2ecf20Sopenharmony_ci break; 3368c2ecf20Sopenharmony_ci case 3: 3378c2ecf20Sopenharmony_ci case 4: 3388c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x24, 0x03, 0x03); 3398c2ecf20Sopenharmony_ci break; 3408c2ecf20Sopenharmony_ci case 5: 3418c2ecf20Sopenharmony_ci case 6: 3428c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x34, 0x03, 0x03); 3438c2ecf20Sopenharmony_ci break; 3448c2ecf20Sopenharmony_ci case 7: 3458c2ecf20Sopenharmony_ci case 8: 3468c2ecf20Sopenharmony_ci regmap_update_bits(data->chip->regmap, 0x44, 0x03, 0x03); 3478c2ecf20Sopenharmony_ci break; 3488c2ecf20Sopenharmony_ci } 3498c2ecf20Sopenharmony_ci} 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_cistatic int cdce925_clk_prepare(struct clk_hw *hw) 3528c2ecf20Sopenharmony_ci{ 3538c2ecf20Sopenharmony_ci struct clk_cdce925_output *data = to_clk_cdce925_output(hw); 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci cdce925_clk_set_pdiv(data, data->pdiv); 3568c2ecf20Sopenharmony_ci cdce925_clk_activate(data); 3578c2ecf20Sopenharmony_ci return 0; 3588c2ecf20Sopenharmony_ci} 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_cistatic void cdce925_clk_unprepare(struct clk_hw *hw) 3618c2ecf20Sopenharmony_ci{ 3628c2ecf20Sopenharmony_ci struct clk_cdce925_output *data = to_clk_cdce925_output(hw); 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci /* Disable clock by setting divider to "0" */ 3658c2ecf20Sopenharmony_ci cdce925_clk_set_pdiv(data, 0); 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_cistatic unsigned long cdce925_clk_recalc_rate(struct clk_hw *hw, 3698c2ecf20Sopenharmony_ci unsigned long parent_rate) 3708c2ecf20Sopenharmony_ci{ 3718c2ecf20Sopenharmony_ci struct clk_cdce925_output *data = to_clk_cdce925_output(hw); 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci if (data->pdiv) 3748c2ecf20Sopenharmony_ci return parent_rate / data->pdiv; 3758c2ecf20Sopenharmony_ci return 0; 3768c2ecf20Sopenharmony_ci} 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_cistatic u16 cdce925_calc_divider(unsigned long rate, 3798c2ecf20Sopenharmony_ci unsigned long parent_rate) 3808c2ecf20Sopenharmony_ci{ 3818c2ecf20Sopenharmony_ci unsigned long divider; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci if (!rate) 3848c2ecf20Sopenharmony_ci return 0; 3858c2ecf20Sopenharmony_ci if (rate >= parent_rate) 3868c2ecf20Sopenharmony_ci return 1; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci divider = DIV_ROUND_CLOSEST(parent_rate, rate); 3898c2ecf20Sopenharmony_ci if (divider > 0x7F) 3908c2ecf20Sopenharmony_ci divider = 0x7F; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci return (u16)divider; 3938c2ecf20Sopenharmony_ci} 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_cistatic unsigned long cdce925_clk_best_parent_rate( 3968c2ecf20Sopenharmony_ci struct clk_hw *hw, unsigned long rate) 3978c2ecf20Sopenharmony_ci{ 3988c2ecf20Sopenharmony_ci struct clk *pll = clk_get_parent(hw->clk); 3998c2ecf20Sopenharmony_ci struct clk *root = clk_get_parent(pll); 4008c2ecf20Sopenharmony_ci unsigned long root_rate = clk_get_rate(root); 4018c2ecf20Sopenharmony_ci unsigned long best_rate_error = rate; 4028c2ecf20Sopenharmony_ci u16 pdiv_min; 4038c2ecf20Sopenharmony_ci u16 pdiv_max; 4048c2ecf20Sopenharmony_ci u16 pdiv_best; 4058c2ecf20Sopenharmony_ci u16 pdiv_now; 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci if (root_rate % rate == 0) 4088c2ecf20Sopenharmony_ci return root_rate; /* Don't need the PLL, use bypass */ 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci pdiv_min = (u16)max(1ul, DIV_ROUND_UP(CDCE925_PLL_FREQUENCY_MIN, rate)); 4118c2ecf20Sopenharmony_ci pdiv_max = (u16)min(127ul, CDCE925_PLL_FREQUENCY_MAX / rate); 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci if (pdiv_min > pdiv_max) 4148c2ecf20Sopenharmony_ci return 0; /* No can do? */ 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci pdiv_best = pdiv_min; 4178c2ecf20Sopenharmony_ci for (pdiv_now = pdiv_min; pdiv_now < pdiv_max; ++pdiv_now) { 4188c2ecf20Sopenharmony_ci unsigned long target_rate = rate * pdiv_now; 4198c2ecf20Sopenharmony_ci long pll_rate = clk_round_rate(pll, target_rate); 4208c2ecf20Sopenharmony_ci unsigned long actual_rate; 4218c2ecf20Sopenharmony_ci unsigned long rate_error; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci if (pll_rate <= 0) 4248c2ecf20Sopenharmony_ci continue; 4258c2ecf20Sopenharmony_ci actual_rate = pll_rate / pdiv_now; 4268c2ecf20Sopenharmony_ci rate_error = abs((long)actual_rate - (long)rate); 4278c2ecf20Sopenharmony_ci if (rate_error < best_rate_error) { 4288c2ecf20Sopenharmony_ci pdiv_best = pdiv_now; 4298c2ecf20Sopenharmony_ci best_rate_error = rate_error; 4308c2ecf20Sopenharmony_ci } 4318c2ecf20Sopenharmony_ci /* TODO: Consider PLL frequency based on smaller n/m values 4328c2ecf20Sopenharmony_ci * and pick the better one if the error is equal */ 4338c2ecf20Sopenharmony_ci } 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci return rate * pdiv_best; 4368c2ecf20Sopenharmony_ci} 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_cistatic long cdce925_clk_round_rate(struct clk_hw *hw, unsigned long rate, 4398c2ecf20Sopenharmony_ci unsigned long *parent_rate) 4408c2ecf20Sopenharmony_ci{ 4418c2ecf20Sopenharmony_ci unsigned long l_parent_rate = *parent_rate; 4428c2ecf20Sopenharmony_ci u16 divider = cdce925_calc_divider(rate, l_parent_rate); 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci if (l_parent_rate / divider != rate) { 4458c2ecf20Sopenharmony_ci l_parent_rate = cdce925_clk_best_parent_rate(hw, rate); 4468c2ecf20Sopenharmony_ci divider = cdce925_calc_divider(rate, l_parent_rate); 4478c2ecf20Sopenharmony_ci *parent_rate = l_parent_rate; 4488c2ecf20Sopenharmony_ci } 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci if (divider) 4518c2ecf20Sopenharmony_ci return (long)(l_parent_rate / divider); 4528c2ecf20Sopenharmony_ci return 0; 4538c2ecf20Sopenharmony_ci} 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_cistatic int cdce925_clk_set_rate(struct clk_hw *hw, unsigned long rate, 4568c2ecf20Sopenharmony_ci unsigned long parent_rate) 4578c2ecf20Sopenharmony_ci{ 4588c2ecf20Sopenharmony_ci struct clk_cdce925_output *data = to_clk_cdce925_output(hw); 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci data->pdiv = cdce925_calc_divider(rate, parent_rate); 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_ci return 0; 4638c2ecf20Sopenharmony_ci} 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_cistatic const struct clk_ops cdce925_clk_ops = { 4668c2ecf20Sopenharmony_ci .prepare = cdce925_clk_prepare, 4678c2ecf20Sopenharmony_ci .unprepare = cdce925_clk_unprepare, 4688c2ecf20Sopenharmony_ci .recalc_rate = cdce925_clk_recalc_rate, 4698c2ecf20Sopenharmony_ci .round_rate = cdce925_clk_round_rate, 4708c2ecf20Sopenharmony_ci .set_rate = cdce925_clk_set_rate, 4718c2ecf20Sopenharmony_ci}; 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_cistatic u16 cdce925_y1_calc_divider(unsigned long rate, 4758c2ecf20Sopenharmony_ci unsigned long parent_rate) 4768c2ecf20Sopenharmony_ci{ 4778c2ecf20Sopenharmony_ci unsigned long divider; 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_ci if (!rate) 4808c2ecf20Sopenharmony_ci return 0; 4818c2ecf20Sopenharmony_ci if (rate >= parent_rate) 4828c2ecf20Sopenharmony_ci return 1; 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci divider = DIV_ROUND_CLOSEST(parent_rate, rate); 4858c2ecf20Sopenharmony_ci if (divider > 0x3FF) /* Y1 has 10-bit divider */ 4868c2ecf20Sopenharmony_ci divider = 0x3FF; 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci return (u16)divider; 4898c2ecf20Sopenharmony_ci} 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_cistatic long cdce925_clk_y1_round_rate(struct clk_hw *hw, unsigned long rate, 4928c2ecf20Sopenharmony_ci unsigned long *parent_rate) 4938c2ecf20Sopenharmony_ci{ 4948c2ecf20Sopenharmony_ci unsigned long l_parent_rate = *parent_rate; 4958c2ecf20Sopenharmony_ci u16 divider = cdce925_y1_calc_divider(rate, l_parent_rate); 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci if (divider) 4988c2ecf20Sopenharmony_ci return (long)(l_parent_rate / divider); 4998c2ecf20Sopenharmony_ci return 0; 5008c2ecf20Sopenharmony_ci} 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_cistatic int cdce925_clk_y1_set_rate(struct clk_hw *hw, unsigned long rate, 5038c2ecf20Sopenharmony_ci unsigned long parent_rate) 5048c2ecf20Sopenharmony_ci{ 5058c2ecf20Sopenharmony_ci struct clk_cdce925_output *data = to_clk_cdce925_output(hw); 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci data->pdiv = cdce925_y1_calc_divider(rate, parent_rate); 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci return 0; 5108c2ecf20Sopenharmony_ci} 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_cistatic const struct clk_ops cdce925_clk_y1_ops = { 5138c2ecf20Sopenharmony_ci .prepare = cdce925_clk_prepare, 5148c2ecf20Sopenharmony_ci .unprepare = cdce925_clk_unprepare, 5158c2ecf20Sopenharmony_ci .recalc_rate = cdce925_clk_recalc_rate, 5168c2ecf20Sopenharmony_ci .round_rate = cdce925_clk_y1_round_rate, 5178c2ecf20Sopenharmony_ci .set_rate = cdce925_clk_y1_set_rate, 5188c2ecf20Sopenharmony_ci}; 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci#define CDCE925_I2C_COMMAND_BLOCK_TRANSFER 0x00 5218c2ecf20Sopenharmony_ci#define CDCE925_I2C_COMMAND_BYTE_TRANSFER 0x80 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_cistatic int cdce925_regmap_i2c_write( 5248c2ecf20Sopenharmony_ci void *context, const void *data, size_t count) 5258c2ecf20Sopenharmony_ci{ 5268c2ecf20Sopenharmony_ci struct device *dev = context; 5278c2ecf20Sopenharmony_ci struct i2c_client *i2c = to_i2c_client(dev); 5288c2ecf20Sopenharmony_ci int ret; 5298c2ecf20Sopenharmony_ci u8 reg_data[2]; 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci if (count != 2) 5328c2ecf20Sopenharmony_ci return -ENOTSUPP; 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci /* First byte is command code */ 5358c2ecf20Sopenharmony_ci reg_data[0] = CDCE925_I2C_COMMAND_BYTE_TRANSFER | ((u8 *)data)[0]; 5368c2ecf20Sopenharmony_ci reg_data[1] = ((u8 *)data)[1]; 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci dev_dbg(&i2c->dev, "%s(%zu) %#x %#x\n", __func__, count, 5398c2ecf20Sopenharmony_ci reg_data[0], reg_data[1]); 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci ret = i2c_master_send(i2c, reg_data, count); 5428c2ecf20Sopenharmony_ci if (likely(ret == count)) 5438c2ecf20Sopenharmony_ci return 0; 5448c2ecf20Sopenharmony_ci else if (ret < 0) 5458c2ecf20Sopenharmony_ci return ret; 5468c2ecf20Sopenharmony_ci else 5478c2ecf20Sopenharmony_ci return -EIO; 5488c2ecf20Sopenharmony_ci} 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_cistatic int cdce925_regmap_i2c_read(void *context, 5518c2ecf20Sopenharmony_ci const void *reg, size_t reg_size, void *val, size_t val_size) 5528c2ecf20Sopenharmony_ci{ 5538c2ecf20Sopenharmony_ci struct device *dev = context; 5548c2ecf20Sopenharmony_ci struct i2c_client *i2c = to_i2c_client(dev); 5558c2ecf20Sopenharmony_ci struct i2c_msg xfer[2]; 5568c2ecf20Sopenharmony_ci int ret; 5578c2ecf20Sopenharmony_ci u8 reg_data[2]; 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci if (reg_size != 1) 5608c2ecf20Sopenharmony_ci return -ENOTSUPP; 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci xfer[0].addr = i2c->addr; 5638c2ecf20Sopenharmony_ci xfer[0].flags = 0; 5648c2ecf20Sopenharmony_ci xfer[0].buf = reg_data; 5658c2ecf20Sopenharmony_ci if (val_size == 1) { 5668c2ecf20Sopenharmony_ci reg_data[0] = 5678c2ecf20Sopenharmony_ci CDCE925_I2C_COMMAND_BYTE_TRANSFER | ((u8 *)reg)[0]; 5688c2ecf20Sopenharmony_ci xfer[0].len = 1; 5698c2ecf20Sopenharmony_ci } else { 5708c2ecf20Sopenharmony_ci reg_data[0] = 5718c2ecf20Sopenharmony_ci CDCE925_I2C_COMMAND_BLOCK_TRANSFER | ((u8 *)reg)[0]; 5728c2ecf20Sopenharmony_ci reg_data[1] = val_size; 5738c2ecf20Sopenharmony_ci xfer[0].len = 2; 5748c2ecf20Sopenharmony_ci } 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci xfer[1].addr = i2c->addr; 5778c2ecf20Sopenharmony_ci xfer[1].flags = I2C_M_RD; 5788c2ecf20Sopenharmony_ci xfer[1].len = val_size; 5798c2ecf20Sopenharmony_ci xfer[1].buf = val; 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ci ret = i2c_transfer(i2c->adapter, xfer, 2); 5828c2ecf20Sopenharmony_ci if (likely(ret == 2)) { 5838c2ecf20Sopenharmony_ci dev_dbg(&i2c->dev, "%s(%zu, %zu) %#x %#x\n", __func__, 5848c2ecf20Sopenharmony_ci reg_size, val_size, reg_data[0], *((u8 *)val)); 5858c2ecf20Sopenharmony_ci return 0; 5868c2ecf20Sopenharmony_ci } else if (ret < 0) 5878c2ecf20Sopenharmony_ci return ret; 5888c2ecf20Sopenharmony_ci else 5898c2ecf20Sopenharmony_ci return -EIO; 5908c2ecf20Sopenharmony_ci} 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_cistatic struct clk_hw * 5938c2ecf20Sopenharmony_ciof_clk_cdce925_get(struct of_phandle_args *clkspec, void *_data) 5948c2ecf20Sopenharmony_ci{ 5958c2ecf20Sopenharmony_ci struct clk_cdce925_chip *data = _data; 5968c2ecf20Sopenharmony_ci unsigned int idx = clkspec->args[0]; 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci if (idx >= ARRAY_SIZE(data->clk)) { 5998c2ecf20Sopenharmony_ci pr_err("%s: invalid index %u\n", __func__, idx); 6008c2ecf20Sopenharmony_ci return ERR_PTR(-EINVAL); 6018c2ecf20Sopenharmony_ci } 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci return &data->clk[idx].hw; 6048c2ecf20Sopenharmony_ci} 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_cistatic void cdce925_regulator_disable(void *regulator) 6078c2ecf20Sopenharmony_ci{ 6088c2ecf20Sopenharmony_ci regulator_disable(regulator); 6098c2ecf20Sopenharmony_ci} 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_cistatic int cdce925_regulator_enable(struct device *dev, const char *name) 6128c2ecf20Sopenharmony_ci{ 6138c2ecf20Sopenharmony_ci struct regulator *regulator; 6148c2ecf20Sopenharmony_ci int err; 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci regulator = devm_regulator_get(dev, name); 6178c2ecf20Sopenharmony_ci if (IS_ERR(regulator)) 6188c2ecf20Sopenharmony_ci return PTR_ERR(regulator); 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci err = regulator_enable(regulator); 6218c2ecf20Sopenharmony_ci if (err) { 6228c2ecf20Sopenharmony_ci dev_err(dev, "Failed to enable %s: %d\n", name, err); 6238c2ecf20Sopenharmony_ci return err; 6248c2ecf20Sopenharmony_ci } 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_ci return devm_add_action_or_reset(dev, cdce925_regulator_disable, 6278c2ecf20Sopenharmony_ci regulator); 6288c2ecf20Sopenharmony_ci} 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci/* The CDCE925 uses a funky way to read/write registers. Bulk mode is 6318c2ecf20Sopenharmony_ci * just weird, so just use the single byte mode exclusively. */ 6328c2ecf20Sopenharmony_cistatic struct regmap_bus regmap_cdce925_bus = { 6338c2ecf20Sopenharmony_ci .write = cdce925_regmap_i2c_write, 6348c2ecf20Sopenharmony_ci .read = cdce925_regmap_i2c_read, 6358c2ecf20Sopenharmony_ci}; 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_cistatic int cdce925_probe(struct i2c_client *client, 6388c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 6398c2ecf20Sopenharmony_ci{ 6408c2ecf20Sopenharmony_ci struct clk_cdce925_chip *data; 6418c2ecf20Sopenharmony_ci struct device_node *node = client->dev.of_node; 6428c2ecf20Sopenharmony_ci const char *parent_name; 6438c2ecf20Sopenharmony_ci const char *pll_clk_name[MAX_NUMBER_OF_PLLS] = {NULL,}; 6448c2ecf20Sopenharmony_ci struct clk_init_data init; 6458c2ecf20Sopenharmony_ci u32 value; 6468c2ecf20Sopenharmony_ci int i; 6478c2ecf20Sopenharmony_ci int err; 6488c2ecf20Sopenharmony_ci struct device_node *np_output; 6498c2ecf20Sopenharmony_ci char child_name[6]; 6508c2ecf20Sopenharmony_ci struct regmap_config config = { 6518c2ecf20Sopenharmony_ci .name = "configuration0", 6528c2ecf20Sopenharmony_ci .reg_bits = 8, 6538c2ecf20Sopenharmony_ci .val_bits = 8, 6548c2ecf20Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 6558c2ecf20Sopenharmony_ci }; 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci dev_dbg(&client->dev, "%s\n", __func__); 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci err = cdce925_regulator_enable(&client->dev, "vdd"); 6608c2ecf20Sopenharmony_ci if (err) 6618c2ecf20Sopenharmony_ci return err; 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_ci err = cdce925_regulator_enable(&client->dev, "vddout"); 6648c2ecf20Sopenharmony_ci if (err) 6658c2ecf20Sopenharmony_ci return err; 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 6688c2ecf20Sopenharmony_ci if (!data) 6698c2ecf20Sopenharmony_ci return -ENOMEM; 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci data->i2c_client = client; 6728c2ecf20Sopenharmony_ci data->chip_info = &clk_cdce925_chip_info_tbl[id->driver_data]; 6738c2ecf20Sopenharmony_ci config.max_register = CDCE925_OFFSET_PLL + 6748c2ecf20Sopenharmony_ci data->chip_info->num_plls * 0x10 - 1; 6758c2ecf20Sopenharmony_ci data->regmap = devm_regmap_init(&client->dev, ®map_cdce925_bus, 6768c2ecf20Sopenharmony_ci &client->dev, &config); 6778c2ecf20Sopenharmony_ci if (IS_ERR(data->regmap)) { 6788c2ecf20Sopenharmony_ci dev_err(&client->dev, "failed to allocate register map\n"); 6798c2ecf20Sopenharmony_ci return PTR_ERR(data->regmap); 6808c2ecf20Sopenharmony_ci } 6818c2ecf20Sopenharmony_ci i2c_set_clientdata(client, data); 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci parent_name = of_clk_get_parent_name(node, 0); 6848c2ecf20Sopenharmony_ci if (!parent_name) { 6858c2ecf20Sopenharmony_ci dev_err(&client->dev, "missing parent clock\n"); 6868c2ecf20Sopenharmony_ci return -ENODEV; 6878c2ecf20Sopenharmony_ci } 6888c2ecf20Sopenharmony_ci dev_dbg(&client->dev, "parent is: %s\n", parent_name); 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci if (of_property_read_u32(node, "xtal-load-pf", &value) == 0) 6918c2ecf20Sopenharmony_ci regmap_write(data->regmap, 6928c2ecf20Sopenharmony_ci CDCE925_REG_XCSEL, (value << 3) & 0xF8); 6938c2ecf20Sopenharmony_ci /* PWDN bit */ 6948c2ecf20Sopenharmony_ci regmap_update_bits(data->regmap, CDCE925_REG_GLOBAL1, BIT(4), 0); 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci /* Set input source for Y1 to be the XTAL */ 6978c2ecf20Sopenharmony_ci regmap_update_bits(data->regmap, 0x02, BIT(7), 0); 6988c2ecf20Sopenharmony_ci 6998c2ecf20Sopenharmony_ci init.ops = &cdce925_pll_ops; 7008c2ecf20Sopenharmony_ci init.flags = 0; 7018c2ecf20Sopenharmony_ci init.parent_names = &parent_name; 7028c2ecf20Sopenharmony_ci init.num_parents = 1; 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci /* Register PLL clocks */ 7058c2ecf20Sopenharmony_ci for (i = 0; i < data->chip_info->num_plls; ++i) { 7068c2ecf20Sopenharmony_ci pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d", 7078c2ecf20Sopenharmony_ci client->dev.of_node, i); 7088c2ecf20Sopenharmony_ci if (!pll_clk_name[i]) { 7098c2ecf20Sopenharmony_ci err = -ENOMEM; 7108c2ecf20Sopenharmony_ci goto error; 7118c2ecf20Sopenharmony_ci } 7128c2ecf20Sopenharmony_ci init.name = pll_clk_name[i]; 7138c2ecf20Sopenharmony_ci data->pll[i].chip = data; 7148c2ecf20Sopenharmony_ci data->pll[i].hw.init = &init; 7158c2ecf20Sopenharmony_ci data->pll[i].index = i; 7168c2ecf20Sopenharmony_ci err = devm_clk_hw_register(&client->dev, &data->pll[i].hw); 7178c2ecf20Sopenharmony_ci if (err) { 7188c2ecf20Sopenharmony_ci dev_err(&client->dev, "Failed register PLL %d\n", i); 7198c2ecf20Sopenharmony_ci goto error; 7208c2ecf20Sopenharmony_ci } 7218c2ecf20Sopenharmony_ci sprintf(child_name, "PLL%d", i+1); 7228c2ecf20Sopenharmony_ci np_output = of_get_child_by_name(node, child_name); 7238c2ecf20Sopenharmony_ci if (!np_output) 7248c2ecf20Sopenharmony_ci continue; 7258c2ecf20Sopenharmony_ci if (!of_property_read_u32(np_output, 7268c2ecf20Sopenharmony_ci "clock-frequency", &value)) { 7278c2ecf20Sopenharmony_ci err = clk_set_rate(data->pll[i].hw.clk, value); 7288c2ecf20Sopenharmony_ci if (err) 7298c2ecf20Sopenharmony_ci dev_err(&client->dev, 7308c2ecf20Sopenharmony_ci "unable to set PLL frequency %ud\n", 7318c2ecf20Sopenharmony_ci value); 7328c2ecf20Sopenharmony_ci } 7338c2ecf20Sopenharmony_ci if (!of_property_read_u32(np_output, 7348c2ecf20Sopenharmony_ci "spread-spectrum", &value)) { 7358c2ecf20Sopenharmony_ci u8 flag = of_property_read_bool(np_output, 7368c2ecf20Sopenharmony_ci "spread-spectrum-center") ? 0x80 : 0x00; 7378c2ecf20Sopenharmony_ci regmap_update_bits(data->regmap, 7388c2ecf20Sopenharmony_ci 0x16 + (i*CDCE925_OFFSET_PLL), 7398c2ecf20Sopenharmony_ci 0x80, flag); 7408c2ecf20Sopenharmony_ci regmap_update_bits(data->regmap, 7418c2ecf20Sopenharmony_ci 0x12 + (i*CDCE925_OFFSET_PLL), 7428c2ecf20Sopenharmony_ci 0x07, value & 0x07); 7438c2ecf20Sopenharmony_ci } 7448c2ecf20Sopenharmony_ci of_node_put(np_output); 7458c2ecf20Sopenharmony_ci } 7468c2ecf20Sopenharmony_ci 7478c2ecf20Sopenharmony_ci /* Register output clock Y1 */ 7488c2ecf20Sopenharmony_ci init.ops = &cdce925_clk_y1_ops; 7498c2ecf20Sopenharmony_ci init.flags = 0; 7508c2ecf20Sopenharmony_ci init.num_parents = 1; 7518c2ecf20Sopenharmony_ci init.parent_names = &parent_name; /* Mux Y1 to input */ 7528c2ecf20Sopenharmony_ci init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node); 7538c2ecf20Sopenharmony_ci if (!init.name) { 7548c2ecf20Sopenharmony_ci err = -ENOMEM; 7558c2ecf20Sopenharmony_ci goto error; 7568c2ecf20Sopenharmony_ci } 7578c2ecf20Sopenharmony_ci data->clk[0].chip = data; 7588c2ecf20Sopenharmony_ci data->clk[0].hw.init = &init; 7598c2ecf20Sopenharmony_ci data->clk[0].index = 0; 7608c2ecf20Sopenharmony_ci data->clk[0].pdiv = 1; 7618c2ecf20Sopenharmony_ci err = devm_clk_hw_register(&client->dev, &data->clk[0].hw); 7628c2ecf20Sopenharmony_ci kfree(init.name); /* clock framework made a copy of the name */ 7638c2ecf20Sopenharmony_ci if (err) { 7648c2ecf20Sopenharmony_ci dev_err(&client->dev, "clock registration Y1 failed\n"); 7658c2ecf20Sopenharmony_ci goto error; 7668c2ecf20Sopenharmony_ci } 7678c2ecf20Sopenharmony_ci 7688c2ecf20Sopenharmony_ci /* Register output clocks Y2 .. Y5*/ 7698c2ecf20Sopenharmony_ci init.ops = &cdce925_clk_ops; 7708c2ecf20Sopenharmony_ci init.flags = CLK_SET_RATE_PARENT; 7718c2ecf20Sopenharmony_ci init.num_parents = 1; 7728c2ecf20Sopenharmony_ci for (i = 1; i < data->chip_info->num_outputs; ++i) { 7738c2ecf20Sopenharmony_ci init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d", 7748c2ecf20Sopenharmony_ci client->dev.of_node, i+1); 7758c2ecf20Sopenharmony_ci if (!init.name) { 7768c2ecf20Sopenharmony_ci err = -ENOMEM; 7778c2ecf20Sopenharmony_ci goto error; 7788c2ecf20Sopenharmony_ci } 7798c2ecf20Sopenharmony_ci data->clk[i].chip = data; 7808c2ecf20Sopenharmony_ci data->clk[i].hw.init = &init; 7818c2ecf20Sopenharmony_ci data->clk[i].index = i; 7828c2ecf20Sopenharmony_ci data->clk[i].pdiv = 1; 7838c2ecf20Sopenharmony_ci switch (i) { 7848c2ecf20Sopenharmony_ci case 1: 7858c2ecf20Sopenharmony_ci case 2: 7868c2ecf20Sopenharmony_ci /* Mux Y2/3 to PLL1 */ 7878c2ecf20Sopenharmony_ci init.parent_names = &pll_clk_name[0]; 7888c2ecf20Sopenharmony_ci break; 7898c2ecf20Sopenharmony_ci case 3: 7908c2ecf20Sopenharmony_ci case 4: 7918c2ecf20Sopenharmony_ci /* Mux Y4/5 to PLL2 */ 7928c2ecf20Sopenharmony_ci init.parent_names = &pll_clk_name[1]; 7938c2ecf20Sopenharmony_ci break; 7948c2ecf20Sopenharmony_ci case 5: 7958c2ecf20Sopenharmony_ci case 6: 7968c2ecf20Sopenharmony_ci /* Mux Y6/7 to PLL3 */ 7978c2ecf20Sopenharmony_ci init.parent_names = &pll_clk_name[2]; 7988c2ecf20Sopenharmony_ci break; 7998c2ecf20Sopenharmony_ci case 7: 8008c2ecf20Sopenharmony_ci case 8: 8018c2ecf20Sopenharmony_ci /* Mux Y8/9 to PLL4 */ 8028c2ecf20Sopenharmony_ci init.parent_names = &pll_clk_name[3]; 8038c2ecf20Sopenharmony_ci break; 8048c2ecf20Sopenharmony_ci } 8058c2ecf20Sopenharmony_ci err = devm_clk_hw_register(&client->dev, &data->clk[i].hw); 8068c2ecf20Sopenharmony_ci kfree(init.name); /* clock framework made a copy of the name */ 8078c2ecf20Sopenharmony_ci if (err) { 8088c2ecf20Sopenharmony_ci dev_err(&client->dev, "clock registration failed\n"); 8098c2ecf20Sopenharmony_ci goto error; 8108c2ecf20Sopenharmony_ci } 8118c2ecf20Sopenharmony_ci } 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci /* Register the output clocks */ 8148c2ecf20Sopenharmony_ci err = of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce925_get, 8158c2ecf20Sopenharmony_ci data); 8168c2ecf20Sopenharmony_ci if (err) 8178c2ecf20Sopenharmony_ci dev_err(&client->dev, "unable to add OF clock provider\n"); 8188c2ecf20Sopenharmony_ci 8198c2ecf20Sopenharmony_ci err = 0; 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_cierror: 8228c2ecf20Sopenharmony_ci for (i = 0; i < data->chip_info->num_plls; ++i) 8238c2ecf20Sopenharmony_ci /* clock framework made a copy of the name */ 8248c2ecf20Sopenharmony_ci kfree(pll_clk_name[i]); 8258c2ecf20Sopenharmony_ci 8268c2ecf20Sopenharmony_ci return err; 8278c2ecf20Sopenharmony_ci} 8288c2ecf20Sopenharmony_ci 8298c2ecf20Sopenharmony_cistatic const struct i2c_device_id cdce925_id[] = { 8308c2ecf20Sopenharmony_ci { "cdce913", CDCE913 }, 8318c2ecf20Sopenharmony_ci { "cdce925", CDCE925 }, 8328c2ecf20Sopenharmony_ci { "cdce937", CDCE937 }, 8338c2ecf20Sopenharmony_ci { "cdce949", CDCE949 }, 8348c2ecf20Sopenharmony_ci { } 8358c2ecf20Sopenharmony_ci}; 8368c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, cdce925_id); 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_cistatic const struct of_device_id clk_cdce925_of_match[] = { 8398c2ecf20Sopenharmony_ci { .compatible = "ti,cdce913" }, 8408c2ecf20Sopenharmony_ci { .compatible = "ti,cdce925" }, 8418c2ecf20Sopenharmony_ci { .compatible = "ti,cdce937" }, 8428c2ecf20Sopenharmony_ci { .compatible = "ti,cdce949" }, 8438c2ecf20Sopenharmony_ci { }, 8448c2ecf20Sopenharmony_ci}; 8458c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, clk_cdce925_of_match); 8468c2ecf20Sopenharmony_ci 8478c2ecf20Sopenharmony_cistatic struct i2c_driver cdce925_driver = { 8488c2ecf20Sopenharmony_ci .driver = { 8498c2ecf20Sopenharmony_ci .name = "cdce925", 8508c2ecf20Sopenharmony_ci .of_match_table = of_match_ptr(clk_cdce925_of_match), 8518c2ecf20Sopenharmony_ci }, 8528c2ecf20Sopenharmony_ci .probe = cdce925_probe, 8538c2ecf20Sopenharmony_ci .id_table = cdce925_id, 8548c2ecf20Sopenharmony_ci}; 8558c2ecf20Sopenharmony_cimodule_i2c_driver(cdce925_driver); 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ciMODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>"); 8588c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("TI CDCE913/925/937/949 driver"); 8598c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 860