Lines Matching +full:reg +full:- +full:names

1 // SPDX-License-Identifier: GPL-2.0-or-later
7 * Copyright (C) 2011 - 2013 Xilinx Inc.
14 #include <linux/clk-provider.h>
85 * si570_get_divs() - Read clock dividers from HW
98 u8 reg[6]; in si570_get_divs() local
101 err = regmap_bulk_read(data->regmap, SI570_REG_HS_N1 + data->div_offset, in si570_get_divs()
102 reg, ARRAY_SIZE(reg)); in si570_get_divs()
106 *hs_div = ((reg[0] & HS_DIV_MASK) >> HS_DIV_SHIFT) + HS_DIV_OFFSET; in si570_get_divs()
107 *n1 = ((reg[0] & N1_6_2_MASK) << 2) + ((reg[1] & N1_1_0_MASK) >> 6) + 1; in si570_get_divs()
112 tmp = reg[1] & RFREQ_37_32_MASK; in si570_get_divs()
113 tmp = (tmp << 8) + reg[2]; in si570_get_divs()
114 tmp = (tmp << 8) + reg[3]; in si570_get_divs()
115 tmp = (tmp << 8) + reg[4]; in si570_get_divs()
116 tmp = (tmp << 8) + reg[5]; in si570_get_divs()
123 * si570_get_defaults() - Get default values
133 regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_RECALL); in si570_get_defaults()
135 err = si570_get_divs(data, &data->rfreq, &data->n1, &data->hs_div); in si570_get_defaults()
143 fdco = fout * data->n1 * data->hs_div; in si570_get_defaults()
145 data->fxtal = div64_u64(fdco << 24, data->rfreq >> 4); in si570_get_defaults()
147 data->fxtal = div64_u64(fdco << 28, data->rfreq); in si570_get_defaults()
149 data->frequency = fout; in si570_get_defaults()
155 * si570_update_rfreq() - Update clock multiplier
161 u8 reg[5]; in si570_update_rfreq() local
163 reg[0] = ((data->n1 - 1) << 6) | in si570_update_rfreq()
164 ((data->rfreq >> 32) & RFREQ_37_32_MASK); in si570_update_rfreq()
165 reg[1] = (data->rfreq >> 24) & 0xff; in si570_update_rfreq()
166 reg[2] = (data->rfreq >> 16) & 0xff; in si570_update_rfreq()
167 reg[3] = (data->rfreq >> 8) & 0xff; in si570_update_rfreq()
168 reg[4] = data->rfreq & 0xff; in si570_update_rfreq()
170 return regmap_bulk_write(data->regmap, SI570_REG_N1_RFREQ0 + in si570_update_rfreq()
171 data->div_offset, reg, ARRAY_SIZE(reg)); in si570_update_rfreq()
175 * si570_calc_divs() - Caluclate clock dividers
207 *out_rfreq = div64_u64(fdco << 28, data->fxtal); in si570_calc_divs()
215 return -EINVAL; in si570_calc_divs()
230 dev_err(&data->i2c_client->dev, "unable to recalc rate\n"); in si570_recalc_rate()
231 return data->frequency; in si570_recalc_rate()
235 rate = (data->fxtal * rfreq) >> 28; in si570_recalc_rate()
251 if (div64_u64(abs(rate - data->frequency) * 10000LL, in si570_round_rate()
252 data->frequency) < 35) { in si570_round_rate()
253 rfreq = div64_u64((data->rfreq * rate) + in si570_round_rate()
254 div64_u64(data->frequency, 2), data->frequency); in si570_round_rate()
255 n1 = data->n1; in si570_round_rate()
256 hs_div = data->hs_div; in si570_round_rate()
261 dev_err(&data->i2c_client->dev, in si570_round_rate()
271 * si570_set_frequency() - Adjust output frequency
282 err = si570_calc_divs(frequency, data, &data->rfreq, &data->n1, in si570_set_frequency()
283 &data->hs_div); in si570_set_frequency()
288 * The DCO reg should be accessed with a read-modify-write operation in si570_set_frequency()
291 regmap_write(data->regmap, SI570_REG_FREEZE_DCO, SI570_FREEZE_DCO); in si570_set_frequency()
292 regmap_write(data->regmap, SI570_REG_HS_N1 + data->div_offset, in si570_set_frequency()
293 ((data->hs_div - HS_DIV_OFFSET) << HS_DIV_SHIFT) | in si570_set_frequency()
294 (((data->n1 - 1) >> 2) & N1_6_2_MASK)); in si570_set_frequency()
296 regmap_write(data->regmap, SI570_REG_FREEZE_DCO, 0); in si570_set_frequency()
297 regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_NEWFREQ); in si570_set_frequency()
306 * si570_set_frequency_small() - Adjust output frequency
317 * This is a re-implementation of DIV_ROUND_CLOSEST in si570_set_frequency_small()
321 data->rfreq = div64_u64((data->rfreq * frequency) + in si570_set_frequency_small()
322 div_u64(data->frequency, 2), data->frequency); in si570_set_frequency_small()
323 regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_FREEZE_M); in si570_set_frequency_small()
325 regmap_write(data->regmap, SI570_REG_CONTROL, 0); in si570_set_frequency_small()
337 struct i2c_client *client = data->i2c_client; in si570_set_rate()
340 if (rate < SI570_MIN_FREQ || rate > data->max_freq) { in si570_set_rate()
341 dev_err(&client->dev, in si570_set_rate()
343 return -EINVAL; in si570_set_rate()
346 if (div64_u64(abs(rate - data->frequency) * 10000LL, in si570_set_rate()
347 data->frequency) < 35) in si570_set_rate()
355 data->frequency = rate; in si570_set_rate()
366 static bool si570_regmap_is_volatile(struct device *dev, unsigned int reg) in si570_regmap_is_volatile() argument
368 switch (reg) { in si570_regmap_is_volatile()
376 static bool si570_regmap_is_writeable(struct device *dev, unsigned int reg) in si570_regmap_is_writeable() argument
378 switch (reg) { in si570_regmap_is_writeable()
404 enum clk_si570_variant variant = id->driver_data; in si570_probe()
406 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); in si570_probe()
408 return -ENOMEM; in si570_probe()
413 data->hw.init = &init; in si570_probe()
414 data->i2c_client = client; in si570_probe()
417 err = of_property_read_u32(client->dev.of_node, in si570_probe()
418 "temperature-stability", &stability); in si570_probe()
420 dev_err(&client->dev, in si570_probe()
421 "'temperature-stability' property missing\n"); in si570_probe()
426 data->div_offset = SI570_DIV_OFFSET_7PPM; in si570_probe()
428 data->max_freq = SI570_MAX_FREQ; in si570_probe()
430 data->max_freq = SI598_MAX_FREQ; in si570_probe()
433 if (of_property_read_string(client->dev.of_node, "clock-output-names", in si570_probe()
435 init.name = client->dev.of_node->name; in si570_probe()
437 err = of_property_read_u32(client->dev.of_node, "factory-fout", in si570_probe()
440 dev_err(&client->dev, "'factory-fout' property missing\n"); in si570_probe()
444 data->regmap = devm_regmap_init_i2c(client, &si570_regmap_config); in si570_probe()
445 if (IS_ERR(data->regmap)) { in si570_probe()
446 dev_err(&client->dev, "failed to allocate register map\n"); in si570_probe()
447 return PTR_ERR(data->regmap); in si570_probe()
455 err = devm_clk_hw_register(&client->dev, &data->hw); in si570_probe()
457 dev_err(&client->dev, "clock registration failed\n"); in si570_probe()
460 err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get, in si570_probe()
461 &data->hw); in si570_probe()
463 dev_err(&client->dev, "unable to add clk provider\n"); in si570_probe()
468 if (!of_property_read_u32(client->dev.of_node, "clock-frequency", in si570_probe()
470 err = clk_set_rate(data->hw.clk, initial_fout); in si570_probe()
472 of_clk_del_provider(client->dev.of_node); in si570_probe()
478 dev_info(&client->dev, "registered, current frequency %llu Hz\n", in si570_probe()
479 data->frequency); in si570_probe()
486 of_clk_del_provider(client->dev.of_node); in si570_remove()