Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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