/*
 * Driver for TI Multi PLL CDCE913/925/937/949 clock synthesizer
 *
 * This driver always connects the Y1 to the input clock, Y2/Y3 to PLL1,
 * Y4/Y5 to PLL2, and so on. PLL frequency is set on a first-come-first-serve
 * basis. Clients can directly request any frequency that the chip can
 * deliver using the standard clk framework. In addition, the device can
 * be configured and activated via the devicetree.
 *
 * Copyright (C) 2014, Topic Embedded Products
 * Licenced under GPL
 */
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/gcd.h>

/* Each chip has different number of PLLs and outputs, for example:
 * The CECE925 has 2 PLLs which can be routed through dividers to 5 outputs.
 * Model this as 2 PLL clocks which are parents to the outputs.
 */

struct clk_cdce925_chip_info {
	int num_plls;
	int num_outputs;
};

#define MAX_NUMBER_OF_PLLS	4
#define MAX_NUMBER_OF_OUTPUTS	9

#define CDCE925_REG_GLOBAL1	0x01
#define CDCE925_REG_Y1SPIPDIVH	0x02
#define CDCE925_REG_PDIVL	0x03
#define CDCE925_REG_XCSEL	0x05
/* PLL parameters start at 0x10, steps of 0x10 */
#define CDCE925_OFFSET_PLL	0x10
/* Add CDCE925_OFFSET_PLL * (pll) to these registers before sending */
#define CDCE925_PLL_MUX_OUTPUTS	0x14
#define CDCE925_PLL_MULDIV	0x18

#define CDCE925_PLL_FREQUENCY_MIN	 80000000ul
#define CDCE925_PLL_FREQUENCY_MAX	230000000ul
struct clk_cdce925_chip;

struct clk_cdce925_output {
	struct clk_hw hw;
	struct clk_cdce925_chip *chip;
	u8 index;
	u16 pdiv; /* 1..127 for Y2-Y9; 1..1023 for Y1 */
};
#define to_clk_cdce925_output(_hw) \
	container_of(_hw, struct clk_cdce925_output, hw)

struct clk_cdce925_pll {
	struct clk_hw hw;
	struct clk_cdce925_chip *chip;
	u8 index;
	u16 m;   /* 1..511 */
	u16 n;   /* 1..4095 */
};
#define to_clk_cdce925_pll(_hw)	container_of(_hw, struct clk_cdce925_pll, hw)

struct clk_cdce925_chip {
	struct regmap *regmap;
	struct i2c_client *i2c_client;
	const struct clk_cdce925_chip_info *chip_info;
	struct clk_cdce925_pll pll[MAX_NUMBER_OF_PLLS];
	struct clk_cdce925_output clk[MAX_NUMBER_OF_OUTPUTS];
};

/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */

static unsigned long cdce925_pll_calculate_rate(unsigned long parent_rate,
	u16 n, u16 m)
{
	if ((!m || !n) || (m == n))
		return parent_rate; /* In bypass mode runs at same frequency */
	return mult_frac(parent_rate, (unsigned long)n, (unsigned long)m);
}

static unsigned long cdce925_pll_recalc_rate(struct clk_hw *hw,
		unsigned long parent_rate)
{
	/* Output frequency of PLL is Fout = (Fin/Pdiv)*(N/M) */
	struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw);

	return cdce925_pll_calculate_rate(parent_rate, data->n, data->m);
}

static void cdce925_pll_find_rate(unsigned long rate,
		unsigned long parent_rate, u16 *n, u16 *m)
{
	unsigned long un;
	unsigned long um;
	unsigned long g;

	if (rate <= parent_rate) {
		/* Can always deliver parent_rate in bypass mode */
		*n = 0;
		*m = 0;
	} else {
		/* In PLL mode, need to apply min/max range */
		if (rate < CDCE925_PLL_FREQUENCY_MIN)
			rate = CDCE925_PLL_FREQUENCY_MIN;
		else if (rate > CDCE925_PLL_FREQUENCY_MAX)
			rate = CDCE925_PLL_FREQUENCY_MAX;

		g = gcd(rate, parent_rate);
		um = parent_rate / g;
		un = rate / g;
		/* When outside hw range, reduce to fit (rounding errors) */
		while ((un > 4095) || (um > 511)) {
			un >>= 1;
			um >>= 1;
		}
		if (un == 0)
			un = 1;
		if (um == 0)
			um = 1;

		*n = un;
		*m = um;
	}
}

static int cdce925_pll_determine_rate(struct clk_hw *hw,
				      struct clk_rate_request *req)
{
	u16 n, m;

	cdce925_pll_find_rate(req->rate, req->best_parent_rate, &n, &m);
	req->rate = (long)cdce925_pll_calculate_rate(req->best_parent_rate, n, m);

	return 0;
}

static int cdce925_pll_set_rate(struct clk_hw *hw, unsigned long rate,
		unsigned long parent_rate)
{
	struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw);

	if (!rate || (rate == parent_rate)) {
		data->m = 0; /* Bypass mode */
		data->n = 0;
		return 0;
	}

	if ((rate < CDCE925_PLL_FREQUENCY_MIN) ||
		(rate > CDCE925_PLL_FREQUENCY_MAX)) {
		pr_debug("%s: rate %lu outside PLL range.\n", __func__, rate);
		return -EINVAL;
	}

	if (rate < parent_rate) {
		pr_debug("%s: rate %lu less than parent rate %lu.\n", __func__,
			rate, parent_rate);
		return -EINVAL;
	}

	cdce925_pll_find_rate(rate, parent_rate, &data->n, &data->m);
	return 0;
}


/* calculate p = max(0, 4 - int(log2 (n/m))) */
static u8 cdce925_pll_calc_p(u16 n, u16 m)
{
	u8 p;
	u16 r = n / m;

	if (r >= 16)
		return 0;
	p = 4;
	while (r > 1) {
		r >>= 1;
		--p;
	}
	return p;
}

/* Returns VCO range bits for VCO1_0_RANGE */
static u8 cdce925_pll_calc_range_bits(struct clk_hw *hw, u16 n, u16 m)
{
	struct clk *parent = clk_get_parent(hw->clk);
	unsigned long rate = clk_get_rate(parent);

	rate = mult_frac(rate, (unsigned long)n, (unsigned long)m);
	if (rate >= 175000000)
		return 0x3;
	if (rate >= 150000000)
		return 0x02;
	if (rate >= 125000000)
		return 0x01;
	return 0x00;
}

/* I2C clock, hence everything must happen in (un)prepare because this
 * may sleep */
static int cdce925_pll_prepare(struct clk_hw *hw)
{
	struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw);
	u16 n = data->n;
	u16 m = data->m;
	u16 r;
	u8 q;
	u8 p;
	u16 nn;
	u8 pll[4]; /* Bits are spread out over 4 byte registers */
	u8 reg_ofs = data->index * CDCE925_OFFSET_PLL;
	unsigned i;

	if ((!m || !n) || (m == n)) {
		/* Set PLL mux to bypass mode, leave the rest as is */
		regmap_update_bits(data->chip->regmap,
			reg_ofs + CDCE925_PLL_MUX_OUTPUTS, 0x80, 0x80);
	} else {
		/* According to data sheet: */
		/* p = max(0, 4 - int(log2 (n/m))) */
		p = cdce925_pll_calc_p(n, m);
		/* nn = n * 2^p */
		nn = n * BIT(p);
		/* q = int(nn/m) */
		q = nn / m;
		if ((q < 16) || (q > 63)) {
			pr_debug("%s invalid q=%d\n", __func__, q);
			return -EINVAL;
		}
		r = nn - (m*q);
		if (r > 511) {
			pr_debug("%s invalid r=%d\n", __func__, r);
			return -EINVAL;
		}
		pr_debug("%s n=%d m=%d p=%d q=%d r=%d\n", __func__,
			n, m, p, q, r);
		/* encode into register bits */
		pll[0] = n >> 4;
		pll[1] = ((n & 0x0F) << 4) | ((r >> 5) & 0x0F);
		pll[2] = ((r & 0x1F) << 3) | ((q >> 3) & 0x07);
		pll[3] = ((q & 0x07) << 5) | (p << 2) |
				cdce925_pll_calc_range_bits(hw, n, m);
		/* Write to registers */
		for (i = 0; i < ARRAY_SIZE(pll); ++i)
			regmap_write(data->chip->regmap,
				reg_ofs + CDCE925_PLL_MULDIV + i, pll[i]);
		/* Enable PLL */
		regmap_update_bits(data->chip->regmap,
			reg_ofs + CDCE925_PLL_MUX_OUTPUTS, 0x80, 0x00);
	}

	return 0;
}

static void cdce925_pll_unprepare(struct clk_hw *hw)
{
	struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw);
	u8 reg_ofs = data->index * CDCE925_OFFSET_PLL;

	regmap_update_bits(data->chip->regmap,
			reg_ofs + CDCE925_PLL_MUX_OUTPUTS, 0x80, 0x80);
}

static const struct clk_ops cdce925_pll_ops = {
	.prepare = cdce925_pll_prepare,
	.unprepare = cdce925_pll_unprepare,
	.recalc_rate = cdce925_pll_recalc_rate,
	.determine_rate = cdce925_pll_determine_rate,
	.set_rate = cdce925_pll_set_rate,
};


static void cdce925_clk_set_pdiv(struct clk_cdce925_output *data, u16 pdiv)
{
	switch (data->index) {
	case 0:
		regmap_update_bits(data->chip->regmap,
			CDCE925_REG_Y1SPIPDIVH,
			0x03, (pdiv >> 8) & 0x03);
		regmap_write(data->chip->regmap, 0x03, pdiv & 0xFF);
		break;
	case 1:
		regmap_update_bits(data->chip->regmap, 0x16, 0x7F, pdiv);
		break;
	case 2:
		regmap_update_bits(data->chip->regmap, 0x17, 0x7F, pdiv);
		break;
	case 3:
		regmap_update_bits(data->chip->regmap, 0x26, 0x7F, pdiv);
		break;
	case 4:
		regmap_update_bits(data->chip->regmap, 0x27, 0x7F, pdiv);
		break;
	case 5:
		regmap_update_bits(data->chip->regmap, 0x36, 0x7F, pdiv);
		break;
	case 6:
		regmap_update_bits(data->chip->regmap, 0x37, 0x7F, pdiv);
		break;
	case 7:
		regmap_update_bits(data->chip->regmap, 0x46, 0x7F, pdiv);
		break;
	case 8:
		regmap_update_bits(data->chip->regmap, 0x47, 0x7F, pdiv);
		break;
	}
}

static void cdce925_clk_activate(struct clk_cdce925_output *data)
{
	switch (data->index) {
	case 0:
		regmap_update_bits(data->chip->regmap,
			CDCE925_REG_Y1SPIPDIVH, 0x0c, 0x0c);
		break;
	case 1:
	case 2:
		regmap_update_bits(data->chip->regmap, 0x14, 0x03, 0x03);
		break;
	case 3:
	case 4:
		regmap_update_bits(data->chip->regmap, 0x24, 0x03, 0x03);
		break;
	case 5:
	case 6:
		regmap_update_bits(data->chip->regmap, 0x34, 0x03, 0x03);
		break;
	case 7:
	case 8:
		regmap_update_bits(data->chip->regmap, 0x44, 0x03, 0x03);
		break;
	}
}

static int cdce925_clk_prepare(struct clk_hw *hw)
{
	struct clk_cdce925_output *data = to_clk_cdce925_output(hw);

	cdce925_clk_set_pdiv(data, data->pdiv);
	cdce925_clk_activate(data);
	return 0;
}

static void cdce925_clk_unprepare(struct clk_hw *hw)
{
	struct clk_cdce925_output *data = to_clk_cdce925_output(hw);

	/* Disable clock by setting divider to "0" */
	cdce925_clk_set_pdiv(data, 0);
}

static unsigned long cdce925_clk_recalc_rate(struct clk_hw *hw,
		unsigned long parent_rate)
{
	struct clk_cdce925_output *data = to_clk_cdce925_output(hw);

	if (data->pdiv)
		return parent_rate / data->pdiv;
	return 0;
}

static u16 cdce925_calc_divider(unsigned long rate,
		unsigned long parent_rate)
{
	unsigned long divider;

	if (!rate)
		return 0;
	if (rate >= parent_rate)
		return 1;

	divider = DIV_ROUND_CLOSEST(parent_rate, rate);
	if (divider > 0x7F)
		divider = 0x7F;

	return (u16)divider;
}

static unsigned long cdce925_clk_best_parent_rate(
	struct clk_hw *hw, unsigned long rate)
{
	struct clk *pll = clk_get_parent(hw->clk);
	struct clk *root = clk_get_parent(pll);
	unsigned long root_rate = clk_get_rate(root);
	unsigned long best_rate_error = rate;
	u16 pdiv_min;
	u16 pdiv_max;
	u16 pdiv_best;
	u16 pdiv_now;

	if (root_rate % rate == 0)
		return root_rate; /* Don't need the PLL, use bypass */

	pdiv_min = (u16)max(1ul, DIV_ROUND_UP(CDCE925_PLL_FREQUENCY_MIN, rate));
	pdiv_max = (u16)min(127ul, CDCE925_PLL_FREQUENCY_MAX / rate);

	if (pdiv_min > pdiv_max)
		return 0; /* No can do? */

	pdiv_best = pdiv_min;
	for (pdiv_now = pdiv_min; pdiv_now < pdiv_max; ++pdiv_now) {
		unsigned long target_rate = rate * pdiv_now;
		long pll_rate = clk_round_rate(pll, target_rate);
		unsigned long actual_rate;
		unsigned long rate_error;

		if (pll_rate <= 0)
			continue;
		actual_rate = pll_rate / pdiv_now;
		rate_error = abs((long)actual_rate - (long)rate);
		if (rate_error < best_rate_error) {
			pdiv_best = pdiv_now;
			best_rate_error = rate_error;
		}
		/* TODO: Consider PLL frequency based on smaller n/m values
		 * and pick the better one if the error is equal */
	}

	return rate * pdiv_best;
}

static int cdce925_clk_determine_rate(struct clk_hw *hw,
				      struct clk_rate_request *req)
{
	unsigned long l_parent_rate = req->best_parent_rate;
	u16 divider = cdce925_calc_divider(req->rate, l_parent_rate);

	if (l_parent_rate / divider != req->rate) {
		l_parent_rate = cdce925_clk_best_parent_rate(hw, req->rate);
		divider = cdce925_calc_divider(req->rate, l_parent_rate);
		req->best_parent_rate = l_parent_rate;
	}

	if (divider)
		req->rate = (long)(l_parent_rate / divider);
	else
		req->rate = 0;

	return 0;
}

static int cdce925_clk_set_rate(struct clk_hw *hw, unsigned long rate,
		unsigned long parent_rate)
{
	struct clk_cdce925_output *data = to_clk_cdce925_output(hw);

	data->pdiv = cdce925_calc_divider(rate, parent_rate);

	return 0;
}

static const struct clk_ops cdce925_clk_ops = {
	.prepare = cdce925_clk_prepare,
	.unprepare = cdce925_clk_unprepare,
	.recalc_rate = cdce925_clk_recalc_rate,
	.determine_rate = cdce925_clk_determine_rate,
	.set_rate = cdce925_clk_set_rate,
};


static u16 cdce925_y1_calc_divider(unsigned long rate,
		unsigned long parent_rate)
{
	unsigned long divider;

	if (!rate)
		return 0;
	if (rate >= parent_rate)
		return 1;

	divider = DIV_ROUND_CLOSEST(parent_rate, rate);
	if (divider > 0x3FF) /* Y1 has 10-bit divider */
		divider = 0x3FF;

	return (u16)divider;
}

static int cdce925_clk_y1_determine_rate(struct clk_hw *hw,
					 struct clk_rate_request *req)
{
	unsigned long l_parent_rate = req->best_parent_rate;
	u16 divider = cdce925_y1_calc_divider(req->rate, l_parent_rate);

	if (divider)
		req->rate = (long)(l_parent_rate / divider);
	else
		req->rate = 0;

	return 0;
}

static int cdce925_clk_y1_set_rate(struct clk_hw *hw, unsigned long rate,
		unsigned long parent_rate)
{
	struct clk_cdce925_output *data = to_clk_cdce925_output(hw);

	data->pdiv = cdce925_y1_calc_divider(rate, parent_rate);

	return 0;
}

static const struct clk_ops cdce925_clk_y1_ops = {
	.prepare = cdce925_clk_prepare,
	.unprepare = cdce925_clk_unprepare,
	.recalc_rate = cdce925_clk_recalc_rate,
	.determine_rate = cdce925_clk_y1_determine_rate,
	.set_rate = cdce925_clk_y1_set_rate,
};

#define CDCE925_I2C_COMMAND_BLOCK_TRANSFER	0x00
#define CDCE925_I2C_COMMAND_BYTE_TRANSFER	0x80

static int cdce925_regmap_i2c_write(
	void *context, const void *data, size_t count)
{
	struct device *dev = context;
	struct i2c_client *i2c = to_i2c_client(dev);
	int ret;
	u8 reg_data[2];

	if (count != 2)
		return -ENOTSUPP;

	/* First byte is command code */
	reg_data[0] = CDCE925_I2C_COMMAND_BYTE_TRANSFER | ((u8 *)data)[0];
	reg_data[1] = ((u8 *)data)[1];

	dev_dbg(&i2c->dev, "%s(%zu) %#x %#x\n", __func__, count,
			reg_data[0], reg_data[1]);

	ret = i2c_master_send(i2c, reg_data, count);
	if (likely(ret == count))
		return 0;
	else if (ret < 0)
		return ret;
	else
		return -EIO;
}

static int cdce925_regmap_i2c_read(void *context,
	   const void *reg, size_t reg_size, void *val, size_t val_size)
{
	struct device *dev = context;
	struct i2c_client *i2c = to_i2c_client(dev);
	struct i2c_msg xfer[2];
	int ret;
	u8 reg_data[2];

	if (reg_size != 1)
		return -ENOTSUPP;

	xfer[0].addr = i2c->addr;
	xfer[0].flags = 0;
	xfer[0].buf = reg_data;
	if (val_size == 1) {
		reg_data[0] =
			CDCE925_I2C_COMMAND_BYTE_TRANSFER | ((u8 *)reg)[0];
		xfer[0].len = 1;
	} else {
		reg_data[0] =
			CDCE925_I2C_COMMAND_BLOCK_TRANSFER | ((u8 *)reg)[0];
		reg_data[1] = val_size;
		xfer[0].len = 2;
	}

	xfer[1].addr = i2c->addr;
	xfer[1].flags = I2C_M_RD;
	xfer[1].len = val_size;
	xfer[1].buf = val;

	ret = i2c_transfer(i2c->adapter, xfer, 2);
	if (likely(ret == 2)) {
		dev_dbg(&i2c->dev, "%s(%zu, %zu) %#x %#x\n", __func__,
				reg_size, val_size, reg_data[0], *((u8 *)val));
		return 0;
	} else if (ret < 0)
		return ret;
	else
		return -EIO;
}

static struct clk_hw *
of_clk_cdce925_get(struct of_phandle_args *clkspec, void *_data)
{
	struct clk_cdce925_chip *data = _data;
	unsigned int idx = clkspec->args[0];

	if (idx >= ARRAY_SIZE(data->clk)) {
		pr_err("%s: invalid index %u\n", __func__, idx);
		return ERR_PTR(-EINVAL);
	}

	return &data->clk[idx].hw;
}

static int cdce925_regulator_enable(struct device *dev, const char *name)
{
	int err;

	err = devm_regulator_get_enable(dev, name);
	if (err)
		dev_err_probe(dev, err, "Failed to enable %s:\n", name);

	return err;
}

/* The CDCE925 uses a funky way to read/write registers. Bulk mode is
 * just weird, so just use the single byte mode exclusively. */
static const struct regmap_bus regmap_cdce925_bus = {
	.write = cdce925_regmap_i2c_write,
	.read = cdce925_regmap_i2c_read,
};

static int cdce925_probe(struct i2c_client *client)
{
	struct clk_cdce925_chip *data;
	struct device_node *node = client->dev.of_node;
	const char *parent_name;
	const char *pll_clk_name[MAX_NUMBER_OF_PLLS] = {NULL,};
	struct clk_init_data init;
	u32 value;
	int i;
	int err;
	struct device_node *np_output;
	char child_name[6];
	struct regmap_config config = {
		.name = "configuration0",
		.reg_bits = 8,
		.val_bits = 8,
		.cache_type = REGCACHE_MAPLE,
	};

	dev_dbg(&client->dev, "%s\n", __func__);

	err = cdce925_regulator_enable(&client->dev, "vdd");
	if (err)
		return err;

	err = cdce925_regulator_enable(&client->dev, "vddout");
	if (err)
		return err;

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

	data->i2c_client = client;
	data->chip_info = i2c_get_match_data(client);
	config.max_register = CDCE925_OFFSET_PLL +
		data->chip_info->num_plls * 0x10 - 1;
	data->regmap = devm_regmap_init(&client->dev, &regmap_cdce925_bus,
			&client->dev, &config);
	if (IS_ERR(data->regmap)) {
		dev_err(&client->dev, "failed to allocate register map\n");
		return PTR_ERR(data->regmap);
	}
	i2c_set_clientdata(client, data);

	parent_name = of_clk_get_parent_name(node, 0);
	if (!parent_name) {
		dev_err(&client->dev, "missing parent clock\n");
		return -ENODEV;
	}
	dev_dbg(&client->dev, "parent is: %s\n", parent_name);

	if (of_property_read_u32(node, "xtal-load-pf", &value) == 0)
		regmap_write(data->regmap,
			CDCE925_REG_XCSEL, (value << 3) & 0xF8);
	/* PWDN bit */
	regmap_update_bits(data->regmap, CDCE925_REG_GLOBAL1, BIT(4), 0);

	/* Set input source for Y1 to be the XTAL */
	regmap_update_bits(data->regmap, 0x02, BIT(7), 0);

	init.ops = &cdce925_pll_ops;
	init.flags = 0;
	init.parent_names = &parent_name;
	init.num_parents = 1;

	/* Register PLL clocks */
	for (i = 0; i < data->chip_info->num_plls; ++i) {
		pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d",
			client->dev.of_node, i);
		if (!pll_clk_name[i]) {
			err = -ENOMEM;
			goto error;
		}
		init.name = pll_clk_name[i];
		data->pll[i].chip = data;
		data->pll[i].hw.init = &init;
		data->pll[i].index = i;
		err = devm_clk_hw_register(&client->dev, &data->pll[i].hw);
		if (err) {
			dev_err(&client->dev, "Failed register PLL %d\n", i);
			goto error;
		}
		sprintf(child_name, "PLL%d", i+1);
		np_output = of_get_child_by_name(node, child_name);
		if (!np_output)
			continue;
		if (!of_property_read_u32(np_output,
			"clock-frequency", &value)) {
			err = clk_set_rate(data->pll[i].hw.clk, value);
			if (err)
				dev_err(&client->dev,
					"unable to set PLL frequency %ud\n",
					value);
		}
		if (!of_property_read_u32(np_output,
			"spread-spectrum", &value)) {
			u8 flag = of_property_read_bool(np_output,
				"spread-spectrum-center") ? 0x80 : 0x00;
			regmap_update_bits(data->regmap,
				0x16 + (i*CDCE925_OFFSET_PLL),
				0x80, flag);
			regmap_update_bits(data->regmap,
				0x12 + (i*CDCE925_OFFSET_PLL),
				0x07, value & 0x07);
		}
		of_node_put(np_output);
	}

	/* Register output clock Y1 */
	init.ops = &cdce925_clk_y1_ops;
	init.flags = 0;
	init.num_parents = 1;
	init.parent_names = &parent_name; /* Mux Y1 to input */
	init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node);
	if (!init.name) {
		err = -ENOMEM;
		goto error;
	}
	data->clk[0].chip = data;
	data->clk[0].hw.init = &init;
	data->clk[0].index = 0;
	data->clk[0].pdiv = 1;
	err = devm_clk_hw_register(&client->dev, &data->clk[0].hw);
	kfree(init.name); /* clock framework made a copy of the name */
	if (err) {
		dev_err(&client->dev, "clock registration Y1 failed\n");
		goto error;
	}

	/* Register output clocks Y2 .. Y5*/
	init.ops = &cdce925_clk_ops;
	init.flags = CLK_SET_RATE_PARENT;
	init.num_parents = 1;
	for (i = 1; i < data->chip_info->num_outputs; ++i) {
		init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d",
			client->dev.of_node, i+1);
		if (!init.name) {
			err = -ENOMEM;
			goto error;
		}
		data->clk[i].chip = data;
		data->clk[i].hw.init = &init;
		data->clk[i].index = i;
		data->clk[i].pdiv = 1;
		switch (i) {
		case 1:
		case 2:
			/* Mux Y2/3 to PLL1 */
			init.parent_names = &pll_clk_name[0];
			break;
		case 3:
		case 4:
			/* Mux Y4/5 to PLL2 */
			init.parent_names = &pll_clk_name[1];
			break;
		case 5:
		case 6:
			/* Mux Y6/7 to PLL3 */
			init.parent_names = &pll_clk_name[2];
			break;
		case 7:
		case 8:
			/* Mux Y8/9 to PLL4 */
			init.parent_names = &pll_clk_name[3];
			break;
		}
		err = devm_clk_hw_register(&client->dev, &data->clk[i].hw);
		kfree(init.name); /* clock framework made a copy of the name */
		if (err) {
			dev_err(&client->dev, "clock registration failed\n");
			goto error;
		}
	}

	/* Register the output clocks */
	err = of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce925_get,
				  data);
	if (err)
		dev_err(&client->dev, "unable to add OF clock provider\n");

	err = 0;

error:
	for (i = 0; i < data->chip_info->num_plls; ++i)
		/* clock framework made a copy of the name */
		kfree(pll_clk_name[i]);

	return err;
}

static const struct clk_cdce925_chip_info clk_cdce913_info = {
	.num_plls = 1,
	.num_outputs = 3,
};

static const struct clk_cdce925_chip_info clk_cdce925_info = {
	.num_plls = 2,
	.num_outputs = 5,
};

static const struct clk_cdce925_chip_info clk_cdce937_info = {
	.num_plls = 3,
	.num_outputs = 7,
};

static const struct clk_cdce925_chip_info clk_cdce949_info = {
	.num_plls = 4,
	.num_outputs = 9,
};

static const struct i2c_device_id cdce925_id[] = {
	{ "cdce913", (kernel_ulong_t)&clk_cdce913_info },
	{ "cdce925", (kernel_ulong_t)&clk_cdce925_info },
	{ "cdce937", (kernel_ulong_t)&clk_cdce937_info },
	{ "cdce949", (kernel_ulong_t)&clk_cdce949_info },
	{ }
};
MODULE_DEVICE_TABLE(i2c, cdce925_id);

static const struct of_device_id clk_cdce925_of_match[] = {
	{ .compatible = "ti,cdce913", .data = &clk_cdce913_info },
	{ .compatible = "ti,cdce925", .data = &clk_cdce925_info },
	{ .compatible = "ti,cdce937", .data = &clk_cdce937_info },
	{ .compatible = "ti,cdce949", .data = &clk_cdce949_info },
	{ }
};
MODULE_DEVICE_TABLE(of, clk_cdce925_of_match);

static struct i2c_driver cdce925_driver = {
	.driver = {
		.name = "cdce925",
		.of_match_table = clk_cdce925_of_match,
	},
	.probe		= cdce925_probe,
	.id_table	= cdce925_id,
};
module_i2c_driver(cdce925_driver);

MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
MODULE_DESCRIPTION("TI CDCE913/925/937/949 driver");
MODULE_LICENSE("GPL");
