/*
 * clk-si5351.c: Silicon Laboratories Si5351A/B/C I2C Clock Generator
 *
 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
 * Rabeeh Khoury <rabeeh@solid-run.com>
 *
 * References:
 * [1] "Si5351A/B/C Data Sheet"
 *     http://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf
 * [2] "Manually Generating an Si5351 Register Map"
 *     http://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/rational.h>
#include <linux/i2c.h>
#include <linux/of_platform.h>
#include <linux/platform_data/si5351.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <asm/div64.h>

#include "clk-si5351.h"

struct si5351_driver_data;

struct si5351_parameters {
	unsigned long	p1;
	unsigned long	p2;
	unsigned long	p3;
	int		valid;
};

struct si5351_hw_data {
	struct clk_hw			hw;
	struct si5351_driver_data	*drvdata;
	struct si5351_parameters	params;
	unsigned char			num;
};

struct si5351_driver_data {
	enum si5351_variant	variant;
	struct i2c_client	*client;
	struct regmap		*regmap;
	struct clk_onecell_data onecell;

	struct clk		*pxtal;
	const char		*pxtal_name;
	struct clk_hw		xtal;
	struct clk		*pclkin;
	const char		*pclkin_name;
	struct clk_hw		clkin;

	struct si5351_hw_data	pll[2];
	struct si5351_hw_data	*msynth;
	struct si5351_hw_data	*clkout;
};

static const char const *si5351_input_names[] = {
	"xtal", "clkin"
};
static const char const *si5351_pll_names[] = {
	"plla", "pllb", "vxco"
};
static const char const *si5351_msynth_names[] = {
	"ms0", "ms1", "ms2", "ms3", "ms4", "ms5", "ms6", "ms7"
};
static const char const *si5351_clkout_names[] = {
	"clk0", "clk1", "clk2", "clk3", "clk4", "clk5", "clk6", "clk7"
};

/*
 * Si5351 i2c regmap
 */
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
	u32 val;
	int ret;

	ret = regmap_read(drvdata->regmap, reg, &val);
	if (ret) {
		dev_err(&drvdata->client->dev,
			"unable to read from reg%02x\n", reg);
		return 0;
	}

	return (u8)val;
}

static inline int si5351_bulk_read(struct si5351_driver_data *drvdata,
				   u8 reg, u8 count, u8 *buf)
{
	return regmap_bulk_read(drvdata->regmap, reg, buf, count);
}

static inline int si5351_reg_write(struct si5351_driver_data *drvdata,
				   u8 reg, u8 val)
{
	return regmap_write(drvdata->regmap, reg, val);
}

static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
				    u8 reg, u8 count, const u8 *buf)
{
	return regmap_raw_write(drvdata->regmap, reg, buf, count);
}

static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
				  u8 reg, u8 mask, u8 val)
{
	return regmap_update_bits(drvdata->regmap, reg, mask, val);
}

static inline u8 si5351_msynth_params_address(int num)
{
	if (num > 5)
		return SI5351_CLK6_PARAMETERS + (num - 6);
	return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
}

static void si5351_read_parameters(struct si5351_driver_data *drvdata,
				   u8 reg, struct si5351_parameters *params)
{
	u8 buf[SI5351_PARAMETERS_LENGTH];

	switch (reg) {
	case SI5351_CLK6_PARAMETERS:
	case SI5351_CLK7_PARAMETERS:
		buf[0] = si5351_reg_read(drvdata, reg);
		params->p1 = buf[0];
		params->p2 = 0;
		params->p3 = 1;
		break;
	default:
		si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
		params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
		params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
		params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
	}
	params->valid = 1;
}

static void si5351_write_parameters(struct si5351_driver_data *drvdata,
				    u8 reg, struct si5351_parameters *params)
{
	u8 buf[SI5351_PARAMETERS_LENGTH];

	switch (reg) {
	case SI5351_CLK6_PARAMETERS:
	case SI5351_CLK7_PARAMETERS:
		buf[0] = params->p1 & 0xff;
		si5351_reg_write(drvdata, reg, buf[0]);
		break;
	default:
		buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
		buf[1] = params->p3 & 0xff;
		/* save rdiv and divby4 */
		buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
		buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
		buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
		buf[4] = params->p1 & 0xff;
		buf[5] = ((params->p3 & 0xf0000) >> 12) |
			((params->p2 & 0xf0000) >> 16);
		buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
		buf[7] = params->p2 & 0xff;
		si5351_bulk_write(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
	}
}

static bool si5351_regmap_is_volatile(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case SI5351_DEVICE_STATUS:
	case SI5351_INTERRUPT_STATUS:
	case SI5351_PLL_RESET:
		return true;
	}
	return false;
}

static bool si5351_regmap_is_writeable(struct device *dev, unsigned int reg)
{
	/* reserved registers */
	if (reg >= 4 && reg <= 8)
		return false;
	if (reg >= 10 && reg <= 14)
		return false;
	if (reg >= 173 && reg <= 176)
		return false;
	if (reg >= 178 && reg <= 182)
		return false;
	/* read-only */
	if (reg == SI5351_DEVICE_STATUS)
		return false;
	return true;
}

static struct regmap_config si5351_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.cache_type = REGCACHE_RBTREE,
	.max_register = 187,
	.writeable_reg = si5351_regmap_is_writeable,
	.volatile_reg = si5351_regmap_is_volatile,
};

/*
 * Si5351 xtal clock input
 */
static int si5351_xtal_prepare(struct clk_hw *hw)
{
	struct si5351_driver_data *drvdata =
		container_of(hw, struct si5351_driver_data, xtal);
	si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
			SI5351_XTAL_ENABLE, SI5351_XTAL_ENABLE);
	return 0;
}

static void si5351_xtal_unprepare(struct clk_hw *hw)
{
	struct si5351_driver_data *drvdata =
		container_of(hw, struct si5351_driver_data, xtal);
	si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
			SI5351_XTAL_ENABLE, 0);
}

static const struct clk_ops si5351_xtal_ops = {
	.prepare = si5351_xtal_prepare,
	.unprepare = si5351_xtal_unprepare,
};

/*
 * Si5351 clkin clock input (Si5351C only)
 */
static int si5351_clkin_prepare(struct clk_hw *hw)
{
	struct si5351_driver_data *drvdata =
		container_of(hw, struct si5351_driver_data, clkin);
	si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
			SI5351_CLKIN_ENABLE, SI5351_CLKIN_ENABLE);
	return 0;
}

static void si5351_clkin_unprepare(struct clk_hw *hw)
{
	struct si5351_driver_data *drvdata =
		container_of(hw, struct si5351_driver_data, clkin);
	si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
			SI5351_CLKIN_ENABLE, 0);
}

/*
 * CMOS clock source constraints:
 * The input frequency range of the PLL is 10Mhz to 40MHz.
 * If CLKIN is >40MHz, the input divider must be used.
 */
static unsigned long si5351_clkin_recalc_rate(struct clk_hw *hw,
					      unsigned long parent_rate)
{
	struct si5351_driver_data *drvdata =
		container_of(hw, struct si5351_driver_data, clkin);
	unsigned long rate;
	unsigned char idiv;

	rate = parent_rate;
	if (parent_rate > 160000000) {
		idiv = SI5351_CLKIN_DIV_8;
		rate /= 8;
	} else if (parent_rate > 80000000) {
		idiv = SI5351_CLKIN_DIV_4;
		rate /= 4;
	} else if (parent_rate > 40000000) {
		idiv = SI5351_CLKIN_DIV_2;
		rate /= 2;
	} else {
		idiv = SI5351_CLKIN_DIV_1;
	}

	si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
			SI5351_CLKIN_DIV_MASK, idiv);

	dev_dbg(&drvdata->client->dev, "%s - clkin div = %d, rate = %lu\n",
		__func__, (1 << (idiv >> 6)), rate);

	return rate;
}

static const struct clk_ops si5351_clkin_ops = {
	.prepare = si5351_clkin_prepare,
	.unprepare = si5351_clkin_unprepare,
	.recalc_rate = si5351_clkin_recalc_rate,
};

/*
 * Si5351 vxco clock input (Si5351B only)
 */

static int si5351_vxco_prepare(struct clk_hw *hw)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);

	dev_warn(&hwdata->drvdata->client->dev, "VXCO currently unsupported\n");

	return 0;
}

static void si5351_vxco_unprepare(struct clk_hw *hw)
{
}

static unsigned long si5351_vxco_recalc_rate(struct clk_hw *hw,
					     unsigned long parent_rate)
{
	return 0;
}

static int si5351_vxco_set_rate(struct clk_hw *hw, unsigned long rate,
				unsigned long parent)
{
	return 0;
}

static const struct clk_ops si5351_vxco_ops = {
	.prepare = si5351_vxco_prepare,
	.unprepare = si5351_vxco_unprepare,
	.recalc_rate = si5351_vxco_recalc_rate,
	.set_rate = si5351_vxco_set_rate,
};

/*
 * Si5351 pll a/b
 *
 * Feedback Multisynth Divider Equations [2]
 *
 * fVCO = fIN * (a + b/c)
 *
 * with 15 + 0/1048575 <= (a + b/c) <= 90 + 0/1048575 and
 * fIN = fXTAL or fIN = fCLKIN/CLKIN_DIV
 *
 * Feedback Multisynth Register Equations
 *
 * (1) MSNx_P1[17:0] = 128 * a + floor(128 * b/c) - 512
 * (2) MSNx_P2[19:0] = 128 * b - c * floor(128 * b/c) = (128*b) mod c
 * (3) MSNx_P3[19:0] = c
 *
 * Transposing (2) yields: (4) floor(128 * b/c) = (128 * b / MSNx_P2)/c
 *
 * Using (4) on (1) yields:
 * MSNx_P1 = 128 * a + (128 * b/MSNx_P2)/c - 512
 * MSNx_P1 + 512 + MSNx_P2/c = 128 * a + 128 * b/c
 *
 * a + b/c = (MSNx_P1 + MSNx_P2/MSNx_P3 + 512)/128
 *         = (MSNx_P1*MSNx_P3 + MSNx_P2 + 512*MSNx_P3)/(128*MSNx_P3)
 *
 */
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
				int num, enum si5351_pll_src parent)
{
	u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;

	if (parent == SI5351_PLL_SRC_DEFAULT)
		return 0;

	if (num > 2)
		return -EINVAL;

	if (drvdata->variant != SI5351_VARIANT_C &&
	    parent != SI5351_PLL_SRC_XTAL)
		return -EINVAL;

	si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, mask,
			(parent == SI5351_PLL_SRC_XTAL) ? 0 : mask);
	return 0;
}

static unsigned char si5351_pll_get_parent(struct clk_hw *hw)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
	u8 val;

	val = si5351_reg_read(hwdata->drvdata, SI5351_PLL_INPUT_SOURCE);

	return (val & mask) ? 1 : 0;
}

static int si5351_pll_set_parent(struct clk_hw *hw, u8 index)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);

	if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
	    index > 0)
		return -EPERM;

	if (index > 1)
		return -EINVAL;

	return _si5351_pll_reparent(hwdata->drvdata, hwdata->num,
			     (index == 0) ? SI5351_PLL_SRC_XTAL :
			     SI5351_PLL_SRC_CLKIN);
}

static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw,
					    unsigned long parent_rate)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
		SI5351_PLLB_PARAMETERS;
	unsigned long long rate;

	if (!hwdata->params.valid)
		si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);

	if (hwdata->params.p3 == 0)
		return parent_rate;

	/* fVCO = fIN * (P1*P3 + 512*P3 + P2)/(128*P3) */
	rate  = hwdata->params.p1 * hwdata->params.p3;
	rate += 512 * hwdata->params.p3;
	rate += hwdata->params.p2;
	rate *= parent_rate;
	do_div(rate, 128 * hwdata->params.p3);

	dev_dbg(&hwdata->drvdata->client->dev,
		"%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n",
		__func__, __clk_get_name(hwdata->hw.clk),
		hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
		parent_rate, (unsigned long)rate);

	return (unsigned long)rate;
}

static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
				  unsigned long *parent_rate)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	unsigned long rfrac, denom, a, b, c;
	unsigned long long lltmp;

	if (rate < SI5351_PLL_VCO_MIN)
		rate = SI5351_PLL_VCO_MIN;
	if (rate > SI5351_PLL_VCO_MAX)
		rate = SI5351_PLL_VCO_MAX;

	/* determine integer part of feedback equation */
	a = rate / *parent_rate;

	if (a < SI5351_PLL_A_MIN)
		rate = *parent_rate * SI5351_PLL_A_MIN;
	if (a > SI5351_PLL_A_MAX)
		rate = *parent_rate * SI5351_PLL_A_MAX;

	/* find best approximation for b/c = fVCO mod fIN */
	denom = 1000 * 1000;
	lltmp = rate % (*parent_rate);
	lltmp *= denom;
	do_div(lltmp, *parent_rate);
	rfrac = (unsigned long)lltmp;

	b = 0;
	c = 1;
	if (rfrac)
		rational_best_approximation(rfrac, denom,
				    SI5351_PLL_B_MAX, SI5351_PLL_C_MAX, &b, &c);

	/* calculate parameters */
	hwdata->params.p3  = c;
	hwdata->params.p2  = (128 * b) % c;
	hwdata->params.p1  = 128 * a;
	hwdata->params.p1 += (128 * b / c);
	hwdata->params.p1 -= 512;

	/* recalculate rate by fIN * (a + b/c) */
	lltmp  = *parent_rate;
	lltmp *= b;
	do_div(lltmp, c);

	rate  = (unsigned long)lltmp;
	rate += *parent_rate * a;

	dev_dbg(&hwdata->drvdata->client->dev,
		"%s - %s: a = %lu, b = %lu, c = %lu, parent_rate = %lu, rate = %lu\n",
		__func__, __clk_get_name(hwdata->hw.clk), a, b, c,
		*parent_rate, rate);

	return rate;
}

static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long parent_rate)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
		SI5351_PLLB_PARAMETERS;

	/* write multisynth parameters */
	si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);

	/* plla/pllb ctrl is in clk6/clk7 ctrl registers */
	si5351_set_bits(hwdata->drvdata, SI5351_CLK6_CTRL + hwdata->num,
		SI5351_CLK_INTEGER_MODE,
		(hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0);

	dev_dbg(&hwdata->drvdata->client->dev,
		"%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n",
		__func__, __clk_get_name(hwdata->hw.clk),
		hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
		parent_rate, rate);

	return 0;
}

static const struct clk_ops si5351_pll_ops = {
	.set_parent = si5351_pll_set_parent,
	.get_parent = si5351_pll_get_parent,
	.recalc_rate = si5351_pll_recalc_rate,
	.round_rate = si5351_pll_round_rate,
	.set_rate = si5351_pll_set_rate,
};

/*
 * Si5351 multisync divider
 *
 * for fOUT <= 150 MHz:
 *
 * fOUT = (fIN * (a + b/c)) / CLKOUTDIV
 *
 * with 6 + 0/1048575 <= (a + b/c) <= 1800 + 0/1048575 and
 * fIN = fVCO0, fVCO1
 *
 * Output Clock Multisynth Register Equations
 *
 * MSx_P1[17:0] = 128 * a + floor(128 * b/c) - 512
 * MSx_P2[19:0] = 128 * b - c * floor(128 * b/c) = (128*b) mod c
 * MSx_P3[19:0] = c
 *
 * MS[6,7] are integer (P1) divide only, P2 = 0, P3 = 0
 *
 * for 150MHz < fOUT <= 160MHz:
 *
 * MSx_P1 = 0, MSx_P2 = 0, MSx_P3 = 1, MSx_INT = 1, MSx_DIVBY4 = 11b
 */
static int _si5351_msynth_reparent(struct si5351_driver_data *drvdata,
				   int num, enum si5351_multisynth_src parent)
{
	if (parent == SI5351_MULTISYNTH_SRC_DEFAULT)
		return 0;

	if (num > 8)
		return -EINVAL;

	si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, SI5351_CLK_PLL_SELECT,
			(parent == SI5351_MULTISYNTH_SRC_VCO0) ? 0 :
			SI5351_CLK_PLL_SELECT);
	return 0;
}

static unsigned char si5351_msynth_get_parent(struct clk_hw *hw)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	u8 val;

	val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);

	return (val & SI5351_CLK_PLL_SELECT) ? 1 : 0;
}

static int si5351_msynth_set_parent(struct clk_hw *hw, u8 index)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);

	return _si5351_msynth_reparent(hwdata->drvdata, hwdata->num,
			       (index == 0) ? SI5351_MULTISYNTH_SRC_VCO0 :
			       SI5351_MULTISYNTH_SRC_VCO1);
}

static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw,
					       unsigned long parent_rate)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	u8 reg = si5351_msynth_params_address(hwdata->num);
	unsigned long long rate;
	unsigned long m;

	if (!hwdata->params.valid)
		si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);

	if (hwdata->params.p3 == 0)
		return parent_rate;

	/*
	 * multisync0-5: fOUT = (128 * P3 * fIN) / (P1*P3 + P2 + 512*P3)
	 * multisync6-7: fOUT = fIN / P1
	 */
	rate = parent_rate;
	if (hwdata->num > 5) {
		m = hwdata->params.p1;
	} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
		    SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
		m = 4;
	} else {
		rate *= 128 * hwdata->params.p3;
		m = hwdata->params.p1 * hwdata->params.p3;
		m += hwdata->params.p2;
		m += 512 * hwdata->params.p3;
	}

	if (m == 0)
		return 0;
	do_div(rate, m);

	dev_dbg(&hwdata->drvdata->client->dev,
		"%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, m = %lu, parent_rate = %lu, rate = %lu\n",
		__func__, __clk_get_name(hwdata->hw.clk),
		hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
		m, parent_rate, (unsigned long)rate);

	return (unsigned long)rate;
}

static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
				     unsigned long *parent_rate)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	unsigned long long lltmp;
	unsigned long a, b, c;
	int divby4;

	/* multisync6-7 can only handle freqencies < 150MHz */
	if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
		rate = SI5351_MULTISYNTH67_MAX_FREQ;

	/* multisync frequency is 1MHz .. 160MHz */
	if (rate > SI5351_MULTISYNTH_MAX_FREQ)
		rate = SI5351_MULTISYNTH_MAX_FREQ;
	if (rate < SI5351_MULTISYNTH_MIN_FREQ)
		rate = SI5351_MULTISYNTH_MIN_FREQ;

	divby4 = 0;
	if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
		divby4 = 1;

	/* multisync can set pll */
	if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
		/*
		 * find largest integer divider for max
		 * vco frequency and given target rate
		 */
		if (divby4 == 0) {
			lltmp = SI5351_PLL_VCO_MAX;
			do_div(lltmp, rate);
			a = (unsigned long)lltmp;
		} else
			a = 4;

		b = 0;
		c = 1;

		*parent_rate = a * rate;
	} else {
		unsigned long rfrac, denom;

		/* disable divby4 */
		if (divby4) {
			rate = SI5351_MULTISYNTH_DIVBY4_FREQ;
			divby4 = 0;
		}

		/* determine integer part of divider equation */
		a = *parent_rate / rate;
		if (a < SI5351_MULTISYNTH_A_MIN)
			a = SI5351_MULTISYNTH_A_MIN;
		if (hwdata->num >= 6 && a > SI5351_MULTISYNTH67_A_MAX)
			a = SI5351_MULTISYNTH67_A_MAX;
		else if (a > SI5351_MULTISYNTH_A_MAX)
			a = SI5351_MULTISYNTH_A_MAX;

		/* find best approximation for b/c = fVCO mod fOUT */
		denom = 1000 * 1000;
		lltmp = (*parent_rate) % rate;
		lltmp *= denom;
		do_div(lltmp, rate);
		rfrac = (unsigned long)lltmp;

		b = 0;
		c = 1;
		if (rfrac)
			rational_best_approximation(rfrac, denom,
			    SI5351_MULTISYNTH_B_MAX, SI5351_MULTISYNTH_C_MAX,
			    &b, &c);
	}

	/* recalculate rate by fOUT = fIN / (a + b/c) */
	lltmp  = *parent_rate;
	lltmp *= c;
	do_div(lltmp, a * c + b);
	rate  = (unsigned long)lltmp;

	/* calculate parameters */
	if (divby4) {
		hwdata->params.p3 = 1;
		hwdata->params.p2 = 0;
		hwdata->params.p1 = 0;
	} else {
		hwdata->params.p3  = c;
		hwdata->params.p2  = (128 * b) % c;
		hwdata->params.p1  = 128 * a;
		hwdata->params.p1 += (128 * b / c);
		hwdata->params.p1 -= 512;
	}

	dev_dbg(&hwdata->drvdata->client->dev,
		"%s - %s: a = %lu, b = %lu, c = %lu, divby4 = %d, parent_rate = %lu, rate = %lu\n",
		__func__, __clk_get_name(hwdata->hw.clk), a, b, c, divby4,
		*parent_rate, rate);

	return rate;
}

static int si5351_msynth_set_rate(struct clk_hw *hw, unsigned long rate,
				  unsigned long parent_rate)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	u8 reg = si5351_msynth_params_address(hwdata->num);
	int divby4 = 0;

	/* write multisynth parameters */
	si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);

	if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
		divby4 = 1;

	/* enable/disable integer mode and divby4 on multisynth0-5 */
	if (hwdata->num < 6) {
		si5351_set_bits(hwdata->drvdata, reg + 2,
				SI5351_OUTPUT_CLK_DIVBY4,
				(divby4) ? SI5351_OUTPUT_CLK_DIVBY4 : 0);
		si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
			SI5351_CLK_INTEGER_MODE,
			(hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0);
	}

	dev_dbg(&hwdata->drvdata->client->dev,
		"%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, divby4 = %d, parent_rate = %lu, rate = %lu\n",
		__func__, __clk_get_name(hwdata->hw.clk),
		hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
		divby4, parent_rate, rate);

	return 0;
}

static const struct clk_ops si5351_msynth_ops = {
	.set_parent = si5351_msynth_set_parent,
	.get_parent = si5351_msynth_get_parent,
	.recalc_rate = si5351_msynth_recalc_rate,
	.round_rate = si5351_msynth_round_rate,
	.set_rate = si5351_msynth_set_rate,
};

/*
 * Si5351 clkout divider
 */
static int _si5351_clkout_reparent(struct si5351_driver_data *drvdata,
				   int num, enum si5351_clkout_src parent)
{
	u8 val;

	if (num > 8)
		return -EINVAL;

	switch (parent) {
	case SI5351_CLKOUT_SRC_MSYNTH_N:
		val = SI5351_CLK_INPUT_MULTISYNTH_N;
		break;
	case SI5351_CLKOUT_SRC_MSYNTH_0_4:
		/* clk0/clk4 can only connect to its own multisync */
		if (num == 0 || num == 4)
			val = SI5351_CLK_INPUT_MULTISYNTH_N;
		else
			val = SI5351_CLK_INPUT_MULTISYNTH_0_4;
		break;
	case SI5351_CLKOUT_SRC_XTAL:
		val = SI5351_CLK_INPUT_XTAL;
		break;
	case SI5351_CLKOUT_SRC_CLKIN:
		if (drvdata->variant != SI5351_VARIANT_C)
			return -EINVAL;

		val = SI5351_CLK_INPUT_CLKIN;
		break;
	default:
		return 0;
	}

	si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num,
			SI5351_CLK_INPUT_MASK, val);
	return 0;
}

static int _si5351_clkout_set_drive_strength(
	struct si5351_driver_data *drvdata, int num,
	enum si5351_drive_strength drive)
{
	u8 mask;

	if (num > 8)
		return -EINVAL;

	switch (drive) {
	case SI5351_DRIVE_2MA:
		mask = SI5351_CLK_DRIVE_STRENGTH_2MA;
		break;
	case SI5351_DRIVE_4MA:
		mask = SI5351_CLK_DRIVE_STRENGTH_4MA;
		break;
	case SI5351_DRIVE_6MA:
		mask = SI5351_CLK_DRIVE_STRENGTH_6MA;
		break;
	case SI5351_DRIVE_8MA:
		mask = SI5351_CLK_DRIVE_STRENGTH_8MA;
		break;
	default:
		return 0;
	}

	si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num,
			SI5351_CLK_DRIVE_STRENGTH_MASK, mask);
	return 0;
}

static int si5351_clkout_prepare(struct clk_hw *hw)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);

	si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
			SI5351_CLK_POWERDOWN, 0);
	si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
			(1 << hwdata->num), 0);
	return 0;
}

static void si5351_clkout_unprepare(struct clk_hw *hw)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);

	si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
			SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN);
	si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
			(1 << hwdata->num), (1 << hwdata->num));
}

static u8 si5351_clkout_get_parent(struct clk_hw *hw)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	int index = 0;
	unsigned char val;

	val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
	switch (val & SI5351_CLK_INPUT_MASK) {
	case SI5351_CLK_INPUT_MULTISYNTH_N:
		index = 0;
		break;
	case SI5351_CLK_INPUT_MULTISYNTH_0_4:
		index = 1;
		break;
	case SI5351_CLK_INPUT_XTAL:
		index = 2;
		break;
	case SI5351_CLK_INPUT_CLKIN:
		index = 3;
		break;
	}

	return index;
}

static int si5351_clkout_set_parent(struct clk_hw *hw, u8 index)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	enum si5351_clkout_src parent = SI5351_CLKOUT_SRC_DEFAULT;

	switch (index) {
	case 0:
		parent = SI5351_CLKOUT_SRC_MSYNTH_N;
		break;
	case 1:
		parent = SI5351_CLKOUT_SRC_MSYNTH_0_4;
		break;
	case 2:
		parent = SI5351_CLKOUT_SRC_XTAL;
		break;
	case 3:
		parent = SI5351_CLKOUT_SRC_CLKIN;
		break;
	}

	return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
}

static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
					       unsigned long parent_rate)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	unsigned char reg;
	unsigned char rdiv;

	if (hwdata->num > 5)
		reg = si5351_msynth_params_address(hwdata->num) + 2;
	else
		reg = SI5351_CLK6_7_OUTPUT_DIVIDER;

	rdiv = si5351_reg_read(hwdata->drvdata, reg);
	if (hwdata->num == 6) {
		rdiv &= SI5351_OUTPUT_CLK6_DIV_MASK;
	} else {
		rdiv &= SI5351_OUTPUT_CLK_DIV_MASK;
		rdiv >>= SI5351_OUTPUT_CLK_DIV_SHIFT;
	}

	return parent_rate >> rdiv;
}

static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
				     unsigned long *parent_rate)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	unsigned char rdiv;

	/* clkout6/7 can only handle output freqencies < 150MHz */
	if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
		rate = SI5351_CLKOUT67_MAX_FREQ;

	/* clkout freqency is 8kHz - 160MHz */
	if (rate > SI5351_CLKOUT_MAX_FREQ)
		rate = SI5351_CLKOUT_MAX_FREQ;
	if (rate < SI5351_CLKOUT_MIN_FREQ)
		rate = SI5351_CLKOUT_MIN_FREQ;

	/* request frequency if multisync master */
	if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
		/* use r divider for frequencies below 1MHz */
		rdiv = SI5351_OUTPUT_CLK_DIV_1;
		while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
		       rdiv < SI5351_OUTPUT_CLK_DIV_128) {
			rdiv += 1;
			rate *= 2;
		}
		*parent_rate = rate;
	} else {
		unsigned long new_rate, new_err, err;

		/* round to closed rdiv */
		rdiv = SI5351_OUTPUT_CLK_DIV_1;
		new_rate = *parent_rate;
		err = abs(new_rate - rate);
		do {
			new_rate >>= 1;
			new_err = abs(new_rate - rate);
			if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
				break;
			rdiv++;
			err = new_err;
		} while (1);
	}
	rate = *parent_rate >> rdiv;

	dev_dbg(&hwdata->drvdata->client->dev,
		"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
		__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
		*parent_rate, rate);

	return rate;
}

static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
				  unsigned long parent_rate)
{
	struct si5351_hw_data *hwdata =
		container_of(hw, struct si5351_hw_data, hw);
	unsigned long new_rate, new_err, err;
	unsigned char rdiv;

	/* round to closed rdiv */
	rdiv = SI5351_OUTPUT_CLK_DIV_1;
	new_rate = parent_rate;
	err = abs(new_rate - rate);
	do {
		new_rate >>= 1;
		new_err = abs(new_rate - rate);
		if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
			break;
		rdiv++;
		err = new_err;
	} while (1);

	/* write output divider */
	switch (hwdata->num) {
	case 6:
		si5351_set_bits(hwdata->drvdata, SI5351_CLK6_7_OUTPUT_DIVIDER,
				SI5351_OUTPUT_CLK6_DIV_MASK, rdiv);
		break;
	case 7:
		si5351_set_bits(hwdata->drvdata, SI5351_CLK6_7_OUTPUT_DIVIDER,
				SI5351_OUTPUT_CLK_DIV_MASK,
				rdiv << SI5351_OUTPUT_CLK_DIV_SHIFT);
		break;
	default:
		si5351_set_bits(hwdata->drvdata,
				si5351_msynth_params_address(hwdata->num) + 2,
				SI5351_OUTPUT_CLK_DIV_MASK,
				rdiv << SI5351_OUTPUT_CLK_DIV_SHIFT);
	}

	/* powerup clkout */
	si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
			SI5351_CLK_POWERDOWN, 0);

	dev_dbg(&hwdata->drvdata->client->dev,
		"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
		__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
		parent_rate, rate);

	return 0;
}

static const struct clk_ops si5351_clkout_ops = {
	.prepare = si5351_clkout_prepare,
	.unprepare = si5351_clkout_unprepare,
	.set_parent = si5351_clkout_set_parent,
	.get_parent = si5351_clkout_get_parent,
	.recalc_rate = si5351_clkout_recalc_rate,
	.round_rate = si5351_clkout_round_rate,
	.set_rate = si5351_clkout_set_rate,
};

/*
 * Si5351 i2c probe and DT
 */
#ifdef CONFIG_OF
static const struct of_device_id si5351_dt_ids[] = {
	{ .compatible = "silabs,si5351a", .data = (void *)SI5351_VARIANT_A, },
	{ .compatible = "silabs,si5351a-msop",
					 .data = (void *)SI5351_VARIANT_A3, },
	{ .compatible = "silabs,si5351b", .data = (void *)SI5351_VARIANT_B, },
	{ .compatible = "silabs,si5351c", .data = (void *)SI5351_VARIANT_C, },
	{ }
};
MODULE_DEVICE_TABLE(of, si5351_dt_ids);

static int si5351_dt_parse(struct i2c_client *client)
{
	struct device_node *child, *np = client->dev.of_node;
	struct si5351_platform_data *pdata;
	const struct of_device_id *match;
	struct property *prop;
	const __be32 *p;
	int num = 0;
	u32 val;

	if (np == NULL)
		return 0;

	match = of_match_node(si5351_dt_ids, np);
	if (match == NULL)
		return -EINVAL;

	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;

	pdata->variant = (enum si5351_variant)match->data;
	pdata->clk_xtal = of_clk_get(np, 0);
	if (!IS_ERR(pdata->clk_xtal))
		clk_put(pdata->clk_xtal);
	pdata->clk_clkin = of_clk_get(np, 1);
	if (!IS_ERR(pdata->clk_clkin))
		clk_put(pdata->clk_clkin);

	/*
	 * property silabs,pll-source : <num src>, [<..>]
	 * allow to selectively set pll source
	 */
	of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) {
		if (num >= 2) {
			dev_err(&client->dev,
				"invalid pll %d on pll-source prop\n", num);
			return -EINVAL;
		}

		p = of_prop_next_u32(prop, p, &val);
		if (!p) {
			dev_err(&client->dev,
				"missing pll-source for pll %d\n", num);
			return -EINVAL;
		}

		switch (val) {
		case 0:
			pdata->pll_src[num] = SI5351_PLL_SRC_XTAL;
			break;
		case 1:
			if (pdata->variant != SI5351_VARIANT_C) {
				dev_err(&client->dev,
					"invalid parent %d for pll %d\n",
					val, num);
				return -EINVAL;
			}
			pdata->pll_src[num] = SI5351_PLL_SRC_CLKIN;
			break;
		default:
			dev_err(&client->dev,
				 "invalid parent %d for pll %d\n", val, num);
			return -EINVAL;
		}
	}

	/* per clkout properties */
	for_each_child_of_node(np, child) {
		if (of_property_read_u32(child, "reg", &num)) {
			dev_err(&client->dev, "missing reg property of %s\n",
				child->name);
			return -EINVAL;
		}

		if (num >= 8 ||
		    (pdata->variant == SI5351_VARIANT_A3 && num >= 3)) {
			dev_err(&client->dev, "invalid clkout %d\n", num);
			return -EINVAL;
		}

		if (!of_property_read_u32(child, "silabs,multisynth-source",
					  &val)) {
			switch (val) {
			case 0:
				pdata->clkout[num].multisynth_src =
					SI5351_MULTISYNTH_SRC_VCO0;
				break;
			case 1:
				pdata->clkout[num].multisynth_src =
					SI5351_MULTISYNTH_SRC_VCO1;
				break;
			default:
				dev_err(&client->dev,
					"invalid parent %d for multisynth %d\n",
					val, num);
				return -EINVAL;
			}
		}

		if (!of_property_read_u32(child, "silabs,clock-source", &val)) {
			switch (val) {
			case 0:
				pdata->clkout[num].clkout_src =
					SI5351_CLKOUT_SRC_MSYNTH_N;
				break;
			case 1:
				pdata->clkout[num].clkout_src =
					SI5351_CLKOUT_SRC_MSYNTH_0_4;
				break;
			case 2:
				pdata->clkout[num].clkout_src =
					SI5351_CLKOUT_SRC_XTAL;
				break;
			case 3:
				if (pdata->variant != SI5351_VARIANT_C) {
					dev_err(&client->dev,
						"invalid parent %d for clkout %d\n",
						val, num);
					return -EINVAL;
				}
				pdata->clkout[num].clkout_src =
					SI5351_CLKOUT_SRC_CLKIN;
				break;
			default:
				dev_err(&client->dev,
					"invalid parent %d for clkout %d\n",
					val, num);
				return -EINVAL;
			}
		}

		if (!of_property_read_u32(child, "silabs,drive-strength",
					  &val)) {
			switch (val) {
			case SI5351_DRIVE_2MA:
			case SI5351_DRIVE_4MA:
			case SI5351_DRIVE_6MA:
			case SI5351_DRIVE_8MA:
				pdata->clkout[num].drive = val;
				break;
			default:
				dev_err(&client->dev,
					"invalid drive strength %d for clkout %d\n",
					val, num);
				return -EINVAL;
			}
		}

		if (!of_property_read_u32(child, "clock-frequency", &val))
			pdata->clkout[num].rate = val;

		pdata->clkout[num].pll_master =
			of_property_read_bool(child, "silabs,pll-master");
	}
	client->dev.platform_data = pdata;

	return 0;
}
#else
static int si5351_dt_parse(struct i2c_client *client)
{
	return 0;
}
#endif /* CONFIG_OF */

static int si5351_i2c_probe(struct i2c_client *client,
			    const struct i2c_device_id *id)
{
	struct si5351_platform_data *pdata;
	struct si5351_driver_data *drvdata;
	struct clk_init_data init;
	struct clk *clk;
	const char *parent_names[4];
	u8 num_parents, num_clocks;
	int ret, n;

	ret = si5351_dt_parse(client);
	if (ret)
		return ret;

	pdata = client->dev.platform_data;
	if (!pdata)
		return -EINVAL;

	drvdata = devm_kzalloc(&client->dev, sizeof(*drvdata), GFP_KERNEL);
	if (drvdata == NULL) {
		dev_err(&client->dev, "unable to allocate driver data\n");
		return -ENOMEM;
	}

	i2c_set_clientdata(client, drvdata);
	drvdata->client = client;
	drvdata->variant = pdata->variant;
	drvdata->pxtal = pdata->clk_xtal;
	drvdata->pclkin = pdata->clk_clkin;

	drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
	if (IS_ERR(drvdata->regmap)) {
		dev_err(&client->dev, "failed to allocate register map\n");
		return PTR_ERR(drvdata->regmap);
	}

	/* Disable interrupts */
	si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0);
	/* Set disabled output drivers to drive low */
	si5351_reg_write(drvdata, SI5351_CLK3_0_DISABLE_STATE, 0x00);
	si5351_reg_write(drvdata, SI5351_CLK7_4_DISABLE_STATE, 0x00);
	/* Ensure pll select is on XTAL for Si5351A/B */
	if (drvdata->variant != SI5351_VARIANT_C)
		si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
				SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);

	/* setup clock configuration */
	for (n = 0; n < 2; n++) {
		ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
		if (ret) {
			dev_err(&client->dev,
				"failed to reparent pll %d to %d\n",
				n, pdata->pll_src[n]);
			return ret;
		}
	}

	for (n = 0; n < 8; n++) {
		ret = _si5351_msynth_reparent(drvdata, n,
					      pdata->clkout[n].multisynth_src);
		if (ret) {
			dev_err(&client->dev,
				"failed to reparent multisynth %d to %d\n",
				n, pdata->clkout[n].multisynth_src);
			return ret;
		}

		ret = _si5351_clkout_reparent(drvdata, n,
					      pdata->clkout[n].clkout_src);
		if (ret) {
			dev_err(&client->dev,
				"failed to reparent clkout %d to %d\n",
				n, pdata->clkout[n].clkout_src);
			return ret;
		}

		ret = _si5351_clkout_set_drive_strength(drvdata, n,
							pdata->clkout[n].drive);
		if (ret) {
			dev_err(&client->dev,
				"failed set drive strength of clkout%d to %d\n",
				n, pdata->clkout[n].drive);
			return ret;
		}
	}

	/* register xtal input clock gate */
	memset(&init, 0, sizeof(init));
	init.name = si5351_input_names[0];
	init.ops = &si5351_xtal_ops;
	init.flags = 0;
	if (!IS_ERR(drvdata->pxtal)) {
		drvdata->pxtal_name = __clk_get_name(drvdata->pxtal);
		init.parent_names = &drvdata->pxtal_name;
		init.num_parents = 1;
	}
	drvdata->xtal.init = &init;
	clk = devm_clk_register(&client->dev, &drvdata->xtal);
	if (IS_ERR(clk)) {
		dev_err(&client->dev, "unable to register %s\n", init.name);
		return PTR_ERR(clk);
	}

	/* register clkin input clock gate */
	if (drvdata->variant == SI5351_VARIANT_C) {
		memset(&init, 0, sizeof(init));
		init.name = si5351_input_names[1];
		init.ops = &si5351_clkin_ops;
		if (!IS_ERR(drvdata->pclkin)) {
			drvdata->pclkin_name = __clk_get_name(drvdata->pclkin);
			init.parent_names = &drvdata->pclkin_name;
			init.num_parents = 1;
		}
		drvdata->clkin.init = &init;
		clk = devm_clk_register(&client->dev, &drvdata->clkin);
		if (IS_ERR(clk)) {
			dev_err(&client->dev, "unable to register %s\n",
				init.name);
			return PTR_ERR(clk);
		}
	}

	/* Si5351C allows to mux either xtal or clkin to PLL input */
	num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
	parent_names[0] = si5351_input_names[0];
	parent_names[1] = si5351_input_names[1];

	/* register PLLA */
	drvdata->pll[0].num = 0;
	drvdata->pll[0].drvdata = drvdata;
	drvdata->pll[0].hw.init = &init;
	memset(&init, 0, sizeof(init));
	init.name = si5351_pll_names[0];
	init.ops = &si5351_pll_ops;
	init.flags = 0;
	init.parent_names = parent_names;
	init.num_parents = num_parents;
	clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
	if (IS_ERR(clk)) {
		dev_err(&client->dev, "unable to register %s\n", init.name);
		return -EINVAL;
	}

	/* register PLLB or VXCO (Si5351B) */
	drvdata->pll[1].num = 1;
	drvdata->pll[1].drvdata = drvdata;
	drvdata->pll[1].hw.init = &init;
	memset(&init, 0, sizeof(init));
	if (drvdata->variant == SI5351_VARIANT_B) {
		init.name = si5351_pll_names[2];
		init.ops = &si5351_vxco_ops;
		init.flags = CLK_IS_ROOT;
		init.parent_names = NULL;
		init.num_parents = 0;
	} else {
		init.name = si5351_pll_names[1];
		init.ops = &si5351_pll_ops;
		init.flags = 0;
		init.parent_names = parent_names;
		init.num_parents = num_parents;
	}
	clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw);
	if (IS_ERR(clk)) {
		dev_err(&client->dev, "unable to register %s\n", init.name);
		return -EINVAL;
	}

	/* register clk multisync and clk out divider */
	num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8;
	parent_names[0] = si5351_pll_names[0];
	if (drvdata->variant == SI5351_VARIANT_B)
		parent_names[1] = si5351_pll_names[2];
	else
		parent_names[1] = si5351_pll_names[1];

	drvdata->msynth = devm_kzalloc(&client->dev, num_clocks *
				       sizeof(*drvdata->msynth), GFP_KERNEL);
	drvdata->clkout = devm_kzalloc(&client->dev, num_clocks *
				       sizeof(*drvdata->clkout), GFP_KERNEL);

	drvdata->onecell.clk_num = num_clocks;
	drvdata->onecell.clks = devm_kzalloc(&client->dev,
		num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);

	if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
		    !drvdata->onecell.clks))
		return -ENOMEM;

	for (n = 0; n < num_clocks; n++) {
		drvdata->msynth[n].num = n;
		drvdata->msynth[n].drvdata = drvdata;
		drvdata->msynth[n].hw.init = &init;
		memset(&init, 0, sizeof(init));
		init.name = si5351_msynth_names[n];
		init.ops = &si5351_msynth_ops;
		init.flags = 0;
		if (pdata->clkout[n].pll_master)
			init.flags |= CLK_SET_RATE_PARENT;
		init.parent_names = parent_names;
		init.num_parents = 2;
		clk = devm_clk_register(&client->dev, &drvdata->msynth[n].hw);
		if (IS_ERR(clk)) {
			dev_err(&client->dev, "unable to register %s\n",
				init.name);
			return -EINVAL;
		}
	}

	num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
	parent_names[2] = si5351_input_names[0];
	parent_names[3] = si5351_input_names[1];
	for (n = 0; n < num_clocks; n++) {
		parent_names[0] = si5351_msynth_names[n];
		parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
			si5351_msynth_names[4];

		drvdata->clkout[n].num = n;
		drvdata->clkout[n].drvdata = drvdata;
		drvdata->clkout[n].hw.init = &init;
		memset(&init, 0, sizeof(init));
		init.name = si5351_clkout_names[n];
		init.ops = &si5351_clkout_ops;
		init.flags = 0;
		if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N)
			init.flags |= CLK_SET_RATE_PARENT;
		init.parent_names = parent_names;
		init.num_parents = num_parents;
		clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw);
		if (IS_ERR(clk)) {
			dev_err(&client->dev, "unable to register %s\n",
				init.name);
			return -EINVAL;
		}
		drvdata->onecell.clks[n] = clk;
	}

	ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
				  &drvdata->onecell);
	if (ret) {
		dev_err(&client->dev, "unable to add clk provider\n");
		return ret;
	}

	return 0;
}

static const struct i2c_device_id si5351_i2c_ids[] = {
	{ "silabs,si5351", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids);

static struct i2c_driver si5351_driver = {
	.driver = {
		.name = "si5351",
		.of_match_table = of_match_ptr(si5351_dt_ids),
	},
	.probe = si5351_i2c_probe,
	.id_table = si5351_i2c_ids,
};
module_i2c_driver(si5351_driver);

MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com");
MODULE_DESCRIPTION("Silicon Labs Si5351A/B/C clock generator driver");
MODULE_LICENSE("GPL");
