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-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2010, 2011 Ericsson AB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2011 Guenter Roeck.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 2011 - 2013 Xilinx Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Author: Guenter Roeck <guenter.roeck@ericsson.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *	   Sören Brinkmann <soren.brinkmann@xilinx.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) /* Si570 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define SI570_REG_HS_N1		7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define SI570_REG_N1_RFREQ0	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define SI570_REG_RFREQ1	9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define SI570_REG_RFREQ2	10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define SI570_REG_RFREQ3	11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define SI570_REG_RFREQ4	12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define SI570_REG_CONTROL	135
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define SI570_REG_FREEZE_DCO	137
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define SI570_DIV_OFFSET_7PPM	6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define HS_DIV_SHIFT		5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define HS_DIV_MASK		0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define HS_DIV_OFFSET		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define N1_6_2_MASK		0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define N1_1_0_MASK		0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define RFREQ_37_32_MASK	0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define SI570_MIN_FREQ		10000000L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define SI570_MAX_FREQ		1417500000L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define SI598_MAX_FREQ		525000000L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define FDCO_MIN		4850000000LL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define FDCO_MAX		5670000000LL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define SI570_CNTRL_RECALL	(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define SI570_CNTRL_FREEZE_M	(1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define SI570_CNTRL_NEWFREQ	(1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define SI570_FREEZE_DCO	(1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * struct clk_si570:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * @hw:	Clock hw struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * @regmap:	Device's regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * @div_offset:	Rgister offset for dividers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * @max_freq:	Maximum frequency for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * @fxtal:	Factory xtal frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * @n1:		Clock divider N1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * @hs_div:	Clock divider HSDIV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * @rfreq:	Clock multiplier RFREQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * @frequency:	Current output frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * @i2c_client:	I2C client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) struct clk_si570 {
^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) 	unsigned int div_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	u64 max_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	u64 fxtal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	unsigned int n1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	unsigned int hs_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	u64 rfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	u64 frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct i2c_client *i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define to_clk_si570(_hw)	container_of(_hw, struct clk_si570, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) enum clk_si570_variant {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	si57x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	si59x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * si570_get_divs() - Read clock dividers from HW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * @data:	Pointer to struct clk_si570
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * @rfreq:	Fractional multiplier (output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * @n1:		Divider N1 (output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * @hs_div:	Divider HSDIV (output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * Returns 0 on success, negative errno otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * Retrieve clock dividers and multipliers from the HW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static int si570_get_divs(struct clk_si570 *data, u64 *rfreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		unsigned int *n1, unsigned int *hs_div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	u8 reg[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	u64 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	err = regmap_bulk_read(data->regmap, SI570_REG_HS_N1 + data->div_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			reg, ARRAY_SIZE(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	*hs_div = ((reg[0] & HS_DIV_MASK) >> HS_DIV_SHIFT) + HS_DIV_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	*n1 = ((reg[0] & N1_6_2_MASK) << 2) + ((reg[1] & N1_1_0_MASK) >> 6) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	/* Handle invalid cases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (*n1 > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		*n1 &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	tmp = reg[1] & RFREQ_37_32_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	tmp = (tmp << 8) + reg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	tmp = (tmp << 8) + reg[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	tmp = (tmp << 8) + reg[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	tmp = (tmp << 8) + reg[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	*rfreq = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * si570_get_defaults() - Get default values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * @data:	Driver data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * @fout:	Factory frequency output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * Returns 0 on success, negative errno otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int si570_get_defaults(struct clk_si570 *data, u64 fout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	u64 fdco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_RECALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	err = si570_get_divs(data, &data->rfreq, &data->n1, &data->hs_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	 * Accept optional precision loss to avoid arithmetic overflows.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	 * Acceptable per Silicon Labs Application Note AN334.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	fdco = fout * data->n1 * data->hs_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	if (fdco >= (1LL << 36))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		data->fxtal = div64_u64(fdco << 24, data->rfreq >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		data->fxtal = div64_u64(fdco << 28, data->rfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	data->frequency = fout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * si570_update_rfreq() - Update clock multiplier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * @data:	Driver data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * Passes on regmap_bulk_write() return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static int si570_update_rfreq(struct clk_si570 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	u8 reg[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	reg[0] = ((data->n1 - 1) << 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		((data->rfreq >> 32) & RFREQ_37_32_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	reg[1] = (data->rfreq >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	reg[2] = (data->rfreq >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	reg[3] = (data->rfreq >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	reg[4] = data->rfreq & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return regmap_bulk_write(data->regmap, SI570_REG_N1_RFREQ0 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			data->div_offset, reg, ARRAY_SIZE(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * si570_calc_divs() - Caluclate clock dividers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * @frequency:	Target frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * @data:	Driver data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  * @out_rfreq:	RFREG fractional multiplier (output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * @out_n1:	Clock divider N1 (output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  * @out_hs_div:	Clock divider HSDIV (output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * Returns 0 on success, negative errno otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * Calculate the clock dividers (@out_hs_div, @out_n1) and clock multiplier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * (@out_rfreq) for a given target @frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int si570_calc_divs(unsigned long frequency, struct clk_si570 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		u64 *out_rfreq, unsigned int *out_n1, unsigned int *out_hs_div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	unsigned int n1, hs_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	u64 fdco, best_fdco = ULLONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	static const uint8_t si570_hs_div_values[] = { 11, 9, 7, 6, 5, 4 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	for (i = 0; i < ARRAY_SIZE(si570_hs_div_values); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		hs_div = si570_hs_div_values[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		/* Calculate lowest possible value for n1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		n1 = div_u64(div_u64(FDCO_MIN, hs_div), frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		if (!n1 || (n1 & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			n1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		while (n1 <= 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			fdco = (u64)frequency * (u64)hs_div * (u64)n1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			if (fdco > FDCO_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			if (fdco >= FDCO_MIN && fdco < best_fdco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 				*out_n1 = n1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 				*out_hs_div = hs_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				*out_rfreq = div64_u64(fdco << 28, data->fxtal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 				best_fdco = fdco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			n1 += (n1 == 1 ? 1 : 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	if (best_fdco == ULLONG_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static unsigned long si570_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	u64 rfreq, rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	unsigned int n1, hs_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	struct clk_si570 *data = to_clk_si570(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	err = si570_get_divs(data, &rfreq, &n1, &hs_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		dev_err(&data->i2c_client->dev, "unable to recalc rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		return data->frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	rfreq = div_u64(rfreq, hs_div * n1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	rate = (data->fxtal * rfreq) >> 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static long si570_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		unsigned long *parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	u64 rfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	unsigned int n1, hs_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	struct clk_si570 *data = to_clk_si570(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	if (div64_u64(abs(rate - data->frequency) * 10000LL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 				data->frequency) < 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		rfreq = div64_u64((data->rfreq * rate) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 				div64_u64(data->frequency, 2), data->frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		n1 = data->n1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		hs_div = data->hs_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		err = si570_calc_divs(rate, data, &rfreq, &n1, &hs_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			dev_err(&data->i2c_client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 					"unable to round rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  * si570_set_frequency() - Adjust output frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  * @data:	Driver data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  * @frequency:	Target frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  * Update output frequency for big frequency changes (> 3,500 ppm).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int si570_set_frequency(struct clk_si570 *data, unsigned long frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	err = si570_calc_divs(frequency, data, &data->rfreq, &data->n1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			&data->hs_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	 * The DCO reg should be accessed with a read-modify-write operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	 * per AN334
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	regmap_write(data->regmap, SI570_REG_FREEZE_DCO, SI570_FREEZE_DCO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	regmap_write(data->regmap, SI570_REG_HS_N1 + data->div_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			((data->hs_div - HS_DIV_OFFSET) << HS_DIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			(((data->n1 - 1) >> 2) & N1_6_2_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	si570_update_rfreq(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	regmap_write(data->regmap, SI570_REG_FREEZE_DCO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_NEWFREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	/* Applying a new frequency can take up to 10ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	usleep_range(10000, 12000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)  * si570_set_frequency_small() - Adjust output frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)  * @data:	Driver data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)  * @frequency:	Target frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)  * Update output frequency for small frequency changes (< 3,500 ppm).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static int si570_set_frequency_small(struct clk_si570 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 				     unsigned long frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	 * This is a re-implementation of DIV_ROUND_CLOSEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	 * using the div64_u64 function lieu of letting the compiler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	 * insert EABI calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	data->rfreq = div64_u64((data->rfreq * frequency) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			div_u64(data->frequency, 2), data->frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_FREEZE_M);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	si570_update_rfreq(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	regmap_write(data->regmap, SI570_REG_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	/* Applying a new frequency (small change) can take up to 100us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	usleep_range(100, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int si570_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	struct clk_si570 *data = to_clk_si570(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	struct i2c_client *client = data->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	if (rate < SI570_MIN_FREQ || rate > data->max_freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			"requested frequency %lu Hz is out of range\n", rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	if (div64_u64(abs(rate - data->frequency) * 10000LL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 				data->frequency) < 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		err = si570_set_frequency_small(data, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		err = si570_set_frequency(data, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	data->frequency = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	return 0;
^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 const struct clk_ops si570_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	.recalc_rate = si570_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	.round_rate = si570_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	.set_rate = si570_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static bool si570_regmap_is_volatile(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	case SI570_REG_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static bool si570_regmap_is_writeable(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	case SI570_REG_HS_N1 ... (SI570_REG_RFREQ4 + SI570_DIV_OFFSET_7PPM):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	case SI570_REG_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	case SI570_REG_FREEZE_DCO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static const struct regmap_config si570_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	.reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	.val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	.cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	.max_register = 137,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	.writeable_reg = si570_regmap_is_writeable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	.volatile_reg = si570_regmap_is_volatile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static int si570_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	struct clk_si570 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	u32 initial_fout, factory_fout, stability;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	enum clk_si570_variant variant = id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	init.ops = &si570_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	init.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	init.num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	data->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	data->i2c_client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	if (variant == si57x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		err = of_property_read_u32(client->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 				"temperature-stability", &stability);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 				  "'temperature-stability' property missing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		/* adjust register offsets for 7ppm devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		if (stability == 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			data->div_offset = SI570_DIV_OFFSET_7PPM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		data->max_freq = SI570_MAX_FREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		data->max_freq = SI598_MAX_FREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	if (of_property_read_string(client->dev.of_node, "clock-output-names",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			&init.name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		init.name = client->dev.of_node->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	err = of_property_read_u32(client->dev.of_node, "factory-fout",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			&factory_fout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		dev_err(&client->dev, "'factory-fout' property missing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	data->regmap = devm_regmap_init_i2c(client, &si570_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	if (IS_ERR(data->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		dev_err(&client->dev, "failed to allocate register map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		return PTR_ERR(data->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	i2c_set_clientdata(client, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	err = si570_get_defaults(data, factory_fout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	err = devm_clk_hw_register(&client->dev, &data->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		dev_err(&client->dev, "clock registration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 				     &data->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		dev_err(&client->dev, "unable to add clk provider\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	/* Read the requested initial output frequency from device tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	if (!of_property_read_u32(client->dev.of_node, "clock-frequency",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 				&initial_fout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		err = clk_set_rate(data->hw.clk, initial_fout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			of_clk_del_provider(client->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	/* Display a message indicating that we've successfully registered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	dev_info(&client->dev, "registered, current frequency %llu Hz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			data->frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int si570_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	of_clk_del_provider(client->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static const struct i2c_device_id si570_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	{ "si570", si57x },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	{ "si571", si57x },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	{ "si598", si59x },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	{ "si599", si59x },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) MODULE_DEVICE_TABLE(i2c, si570_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static const struct of_device_id clk_si570_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	{ .compatible = "silabs,si570" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	{ .compatible = "silabs,si571" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	{ .compatible = "silabs,si598" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	{ .compatible = "silabs,si599" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) MODULE_DEVICE_TABLE(of, clk_si570_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static struct i2c_driver si570_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		.name = "si570",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		.of_match_table = clk_si570_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	.probe		= si570_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	.remove		= si570_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	.id_table	= si570_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) module_i2c_driver(si570_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) MODULE_DESCRIPTION("Si570 driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) MODULE_LICENSE("GPL");