1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Driver for IDT Versaclock 5
4 *
5 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
6 */
7
8/*
9 * Possible optimizations:
10 * - Use spread spectrum
11 * - Use integer divider in FOD if applicable
12 */
13
14#include <linux/clk.h>
15#include <linux/clk-provider.h>
16#include <linux/delay.h>
17#include <linux/i2c.h>
18#include <linux/interrupt.h>
19#include <linux/mod_devicetable.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_platform.h>
23#include <linux/rational.h>
24#include <linux/regmap.h>
25#include <linux/slab.h>
26
27#include <dt-bindings/clk/versaclock.h>
28
29/* VersaClock5 registers */
30#define VC5_OTP_CONTROL				0x00
31
32/* Factory-reserved register block */
33#define VC5_RSVD_DEVICE_ID			0x01
34#define VC5_RSVD_ADC_GAIN_7_0			0x02
35#define VC5_RSVD_ADC_GAIN_15_8			0x03
36#define VC5_RSVD_ADC_OFFSET_7_0			0x04
37#define VC5_RSVD_ADC_OFFSET_15_8		0x05
38#define VC5_RSVD_TEMPY				0x06
39#define VC5_RSVD_OFFSET_TBIN			0x07
40#define VC5_RSVD_GAIN				0x08
41#define VC5_RSVD_TEST_NP			0x09
42#define VC5_RSVD_UNUSED				0x0a
43#define VC5_RSVD_BANDGAP_TRIM_UP		0x0b
44#define VC5_RSVD_BANDGAP_TRIM_DN		0x0c
45#define VC5_RSVD_CLK_R_12_CLK_AMP_4		0x0d
46#define VC5_RSVD_CLK_R_34_CLK_AMP_4		0x0e
47#define VC5_RSVD_CLK_AMP_123			0x0f
48
49/* Configuration register block */
50#define VC5_PRIM_SRC_SHDN			0x10
51#define VC5_PRIM_SRC_SHDN_EN_XTAL		BIT(7)
52#define VC5_PRIM_SRC_SHDN_EN_CLKIN		BIT(6)
53#define VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ	BIT(3)
54#define VC5_PRIM_SRC_SHDN_SP			BIT(1)
55#define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN		BIT(0)
56
57#define VC5_VCO_BAND				0x11
58#define VC5_XTAL_X1_LOAD_CAP			0x12
59#define VC5_XTAL_X2_LOAD_CAP			0x13
60#define VC5_REF_DIVIDER				0x15
61#define VC5_REF_DIVIDER_SEL_PREDIV2		BIT(7)
62#define VC5_REF_DIVIDER_REF_DIV(n)		((n) & 0x3f)
63
64#define VC5_VCO_CTRL_AND_PREDIV			0x16
65#define VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV	BIT(7)
66
67#define VC5_FEEDBACK_INT_DIV			0x17
68#define VC5_FEEDBACK_INT_DIV_BITS		0x18
69#define VC5_FEEDBACK_FRAC_DIV(n)		(0x19 + (n))
70#define VC5_RC_CONTROL0				0x1e
71#define VC5_RC_CONTROL1				0x1f
72
73/* These registers are named "Unused Factory Reserved Registers" */
74#define VC5_RESERVED_X0(idx)		(0x20 + ((idx) * 0x10))
75#define VC5_RESERVED_X0_BYPASS_SYNC	BIT(7) /* bypass_sync<idx> bit */
76
77/* Output divider control for divider 1,2,3,4 */
78#define VC5_OUT_DIV_CONTROL(idx)	(0x21 + ((idx) * 0x10))
79#define VC5_OUT_DIV_CONTROL_RESET	BIT(7)
80#define VC5_OUT_DIV_CONTROL_SELB_NORM	BIT(3)
81#define VC5_OUT_DIV_CONTROL_SEL_EXT	BIT(2)
82#define VC5_OUT_DIV_CONTROL_INT_MODE	BIT(1)
83#define VC5_OUT_DIV_CONTROL_EN_FOD	BIT(0)
84
85#define VC5_OUT_DIV_FRAC(idx, n)	(0x22 + ((idx) * 0x10) + (n))
86#define VC5_OUT_DIV_FRAC4_OD_SCEE	BIT(1)
87
88#define VC5_OUT_DIV_STEP_SPREAD(idx, n)	(0x26 + ((idx) * 0x10) + (n))
89#define VC5_OUT_DIV_SPREAD_MOD(idx, n)	(0x29 + ((idx) * 0x10) + (n))
90#define VC5_OUT_DIV_SKEW_INT(idx, n)	(0x2b + ((idx) * 0x10) + (n))
91#define VC5_OUT_DIV_INT(idx, n)		(0x2d + ((idx) * 0x10) + (n))
92#define VC5_OUT_DIV_SKEW_FRAC(idx)	(0x2f + ((idx) * 0x10))
93
94/* Clock control register for clock 1,2 */
95#define VC5_CLK_OUTPUT_CFG(idx, n)	(0x60 + ((idx) * 0x2) + (n))
96#define VC5_CLK_OUTPUT_CFG0_CFG_SHIFT	5
97#define VC5_CLK_OUTPUT_CFG0_CFG_MASK GENMASK(7, VC5_CLK_OUTPUT_CFG0_CFG_SHIFT)
98
99#define VC5_CLK_OUTPUT_CFG0_CFG_LVPECL	(VC5_LVPECL)
100#define VC5_CLK_OUTPUT_CFG0_CFG_CMOS		(VC5_CMOS)
101#define VC5_CLK_OUTPUT_CFG0_CFG_HCSL33	(VC5_HCSL33)
102#define VC5_CLK_OUTPUT_CFG0_CFG_LVDS		(VC5_LVDS)
103#define VC5_CLK_OUTPUT_CFG0_CFG_CMOS2		(VC5_CMOS2)
104#define VC5_CLK_OUTPUT_CFG0_CFG_CMOSD		(VC5_CMOSD)
105#define VC5_CLK_OUTPUT_CFG0_CFG_HCSL25	(VC5_HCSL25)
106
107#define VC5_CLK_OUTPUT_CFG0_PWR_SHIFT	3
108#define VC5_CLK_OUTPUT_CFG0_PWR_MASK GENMASK(4, VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
109#define VC5_CLK_OUTPUT_CFG0_PWR_18	(0<<VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
110#define VC5_CLK_OUTPUT_CFG0_PWR_25	(2<<VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
111#define VC5_CLK_OUTPUT_CFG0_PWR_33	(3<<VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
112#define VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT	0
113#define VC5_CLK_OUTPUT_CFG0_SLEW_MASK GENMASK(1, VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
114#define VC5_CLK_OUTPUT_CFG0_SLEW_80	(0<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
115#define VC5_CLK_OUTPUT_CFG0_SLEW_85	(1<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
116#define VC5_CLK_OUTPUT_CFG0_SLEW_90	(2<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
117#define VC5_CLK_OUTPUT_CFG0_SLEW_100	(3<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
118#define VC5_CLK_OUTPUT_CFG1_EN_CLKBUF	BIT(0)
119
120#define VC5_CLK_OE_SHDN				0x68
121#define VC5_CLK_OS_SHDN				0x69
122
123#define VC5_GLOBAL_REGISTER			0x76
124#define VC5_GLOBAL_REGISTER_GLOBAL_RESET	BIT(5)
125
126/* PLL/VCO runs between 2.5 GHz and 3.0 GHz */
127#define VC5_PLL_VCO_MIN				2500000000UL
128#define VC5_PLL_VCO_MAX				3000000000UL
129
130/* VC5 Input mux settings */
131#define VC5_MUX_IN_XIN		BIT(0)
132#define VC5_MUX_IN_CLKIN	BIT(1)
133
134/* Maximum number of clk_out supported by this driver */
135#define VC5_MAX_CLK_OUT_NUM	5
136
137/* Maximum number of FODs supported by this driver */
138#define VC5_MAX_FOD_NUM	4
139
140/* flags to describe chip features */
141/* chip has built-in oscilator */
142#define VC5_HAS_INTERNAL_XTAL	BIT(0)
143/* chip has PFD requency doubler */
144#define VC5_HAS_PFD_FREQ_DBL	BIT(1)
145/* chip has bits to disable FOD sync */
146#define VC5_HAS_BYPASS_SYNC_BIT	BIT(2)
147
148/* Supported IDT VC5 models. */
149enum vc5_model {
150	IDT_VC5_5P49V5923,
151	IDT_VC5_5P49V5925,
152	IDT_VC5_5P49V5933,
153	IDT_VC5_5P49V5935,
154	IDT_VC6_5P49V6901,
155	IDT_VC6_5P49V6965,
156};
157
158/* Structure to describe features of a particular VC5 model */
159struct vc5_chip_info {
160	const enum vc5_model	model;
161	const unsigned int	clk_fod_cnt;
162	const unsigned int	clk_out_cnt;
163	const u32		flags;
164};
165
166struct vc5_driver_data;
167
168struct vc5_hw_data {
169	struct clk_hw		hw;
170	struct vc5_driver_data	*vc5;
171	u32			div_int;
172	u32			div_frc;
173	unsigned int		num;
174};
175
176struct vc5_out_data {
177	struct clk_hw		hw;
178	struct vc5_driver_data	*vc5;
179	unsigned int		num;
180	unsigned int		clk_output_cfg0;
181	unsigned int		clk_output_cfg0_mask;
182};
183
184struct vc5_driver_data {
185	struct i2c_client	*client;
186	struct regmap		*regmap;
187	const struct vc5_chip_info	*chip_info;
188
189	struct clk		*pin_xin;
190	struct clk		*pin_clkin;
191	unsigned char		clk_mux_ins;
192	struct clk_hw		clk_mux;
193	struct clk_hw		clk_mul;
194	struct clk_hw		clk_pfd;
195	struct vc5_hw_data	clk_pll;
196	struct vc5_hw_data	clk_fod[VC5_MAX_FOD_NUM];
197	struct vc5_out_data	clk_out[VC5_MAX_CLK_OUT_NUM];
198};
199
200/*
201 * VersaClock5 i2c regmap
202 */
203static bool vc5_regmap_is_writeable(struct device *dev, unsigned int reg)
204{
205	/* Factory reserved regs, make them read-only */
206	if (reg <= 0xf)
207		return false;
208
209	/* Factory reserved regs, make them read-only */
210	if (reg == 0x14 || reg == 0x1c || reg == 0x1d)
211		return false;
212
213	return true;
214}
215
216static const struct regmap_config vc5_regmap_config = {
217	.reg_bits = 8,
218	.val_bits = 8,
219	.cache_type = REGCACHE_RBTREE,
220	.max_register = 0x76,
221	.writeable_reg = vc5_regmap_is_writeable,
222};
223
224/*
225 * VersaClock5 input multiplexer between XTAL and CLKIN divider
226 */
227static unsigned char vc5_mux_get_parent(struct clk_hw *hw)
228{
229	struct vc5_driver_data *vc5 =
230		container_of(hw, struct vc5_driver_data, clk_mux);
231	const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
232	unsigned int src;
233
234	regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &src);
235	src &= mask;
236
237	if (src == VC5_PRIM_SRC_SHDN_EN_XTAL)
238		return 0;
239
240	if (src == VC5_PRIM_SRC_SHDN_EN_CLKIN)
241		return 1;
242
243	dev_warn(&vc5->client->dev,
244		 "Invalid clock input configuration (%02x)\n", src);
245	return 0;
246}
247
248static int vc5_mux_set_parent(struct clk_hw *hw, u8 index)
249{
250	struct vc5_driver_data *vc5 =
251		container_of(hw, struct vc5_driver_data, clk_mux);
252	const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
253	u8 src;
254
255	if ((index > 1) || !vc5->clk_mux_ins)
256		return -EINVAL;
257
258	if (vc5->clk_mux_ins == (VC5_MUX_IN_CLKIN | VC5_MUX_IN_XIN)) {
259		if (index == 0)
260			src = VC5_PRIM_SRC_SHDN_EN_XTAL;
261		if (index == 1)
262			src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
263	} else {
264		if (index != 0)
265			return -EINVAL;
266
267		if (vc5->clk_mux_ins == VC5_MUX_IN_XIN)
268			src = VC5_PRIM_SRC_SHDN_EN_XTAL;
269		else if (vc5->clk_mux_ins == VC5_MUX_IN_CLKIN)
270			src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
271		else /* Invalid; should have been caught by vc5_probe() */
272			return -EINVAL;
273	}
274
275	return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src);
276}
277
278static const struct clk_ops vc5_mux_ops = {
279	.set_parent	= vc5_mux_set_parent,
280	.get_parent	= vc5_mux_get_parent,
281};
282
283static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw,
284					 unsigned long parent_rate)
285{
286	struct vc5_driver_data *vc5 =
287		container_of(hw, struct vc5_driver_data, clk_mul);
288	unsigned int premul;
289
290	regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &premul);
291	if (premul & VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ)
292		parent_rate *= 2;
293
294	return parent_rate;
295}
296
297static long vc5_dbl_round_rate(struct clk_hw *hw, unsigned long rate,
298			       unsigned long *parent_rate)
299{
300	if ((*parent_rate == rate) || ((*parent_rate * 2) == rate))
301		return rate;
302	else
303		return -EINVAL;
304}
305
306static int vc5_dbl_set_rate(struct clk_hw *hw, unsigned long rate,
307			    unsigned long parent_rate)
308{
309	struct vc5_driver_data *vc5 =
310		container_of(hw, struct vc5_driver_data, clk_mul);
311	u32 mask;
312
313	if ((parent_rate * 2) == rate)
314		mask = VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ;
315	else
316		mask = 0;
317
318	regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN,
319			   VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ,
320			   mask);
321
322	return 0;
323}
324
325static const struct clk_ops vc5_dbl_ops = {
326	.recalc_rate	= vc5_dbl_recalc_rate,
327	.round_rate	= vc5_dbl_round_rate,
328	.set_rate	= vc5_dbl_set_rate,
329};
330
331static unsigned long vc5_pfd_recalc_rate(struct clk_hw *hw,
332					 unsigned long parent_rate)
333{
334	struct vc5_driver_data *vc5 =
335		container_of(hw, struct vc5_driver_data, clk_pfd);
336	unsigned int prediv, div;
337
338	regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv);
339
340	/* The bypass_prediv is set, PLL fed from Ref_in directly. */
341	if (prediv & VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV)
342		return parent_rate;
343
344	regmap_read(vc5->regmap, VC5_REF_DIVIDER, &div);
345
346	/* The Sel_prediv2 is set, PLL fed from prediv2 (Ref_in / 2) */
347	if (div & VC5_REF_DIVIDER_SEL_PREDIV2)
348		return parent_rate / 2;
349	else
350		return parent_rate / VC5_REF_DIVIDER_REF_DIV(div);
351}
352
353static long vc5_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
354			       unsigned long *parent_rate)
355{
356	unsigned long idiv;
357
358	/* PLL cannot operate with input clock above 50 MHz. */
359	if (rate > 50000000)
360		return -EINVAL;
361
362	/* CLKIN within range of PLL input, feed directly to PLL. */
363	if (*parent_rate <= 50000000)
364		return *parent_rate;
365
366	idiv = DIV_ROUND_UP(*parent_rate, rate);
367	if (idiv > 127)
368		return -EINVAL;
369
370	return *parent_rate / idiv;
371}
372
373static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
374			    unsigned long parent_rate)
375{
376	struct vc5_driver_data *vc5 =
377		container_of(hw, struct vc5_driver_data, clk_pfd);
378	unsigned long idiv;
379	u8 div;
380
381	/* CLKIN within range of PLL input, feed directly to PLL. */
382	if (parent_rate <= 50000000) {
383		regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
384				   VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV,
385				   VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV);
386		regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, 0x00);
387		return 0;
388	}
389
390	idiv = DIV_ROUND_UP(parent_rate, rate);
391
392	/* We have dedicated div-2 predivider. */
393	if (idiv == 2)
394		div = VC5_REF_DIVIDER_SEL_PREDIV2;
395	else
396		div = VC5_REF_DIVIDER_REF_DIV(idiv);
397
398	regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, div);
399	regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
400			   VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV, 0);
401
402	return 0;
403}
404
405static const struct clk_ops vc5_pfd_ops = {
406	.recalc_rate	= vc5_pfd_recalc_rate,
407	.round_rate	= vc5_pfd_round_rate,
408	.set_rate	= vc5_pfd_set_rate,
409};
410
411/*
412 * VersaClock5 PLL/VCO
413 */
414static unsigned long vc5_pll_recalc_rate(struct clk_hw *hw,
415					 unsigned long parent_rate)
416{
417	struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
418	struct vc5_driver_data *vc5 = hwdata->vc5;
419	u32 div_int, div_frc;
420	u8 fb[5];
421
422	regmap_bulk_read(vc5->regmap, VC5_FEEDBACK_INT_DIV, fb, 5);
423
424	div_int = (fb[0] << 4) | (fb[1] >> 4);
425	div_frc = (fb[2] << 16) | (fb[3] << 8) | fb[4];
426
427	/* The PLL divider has 12 integer bits and 24 fractional bits */
428	return (parent_rate * div_int) + ((parent_rate * div_frc) >> 24);
429}
430
431static long vc5_pll_round_rate(struct clk_hw *hw, unsigned long rate,
432			       unsigned long *parent_rate)
433{
434	struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
435	u32 div_int;
436	u64 div_frc;
437
438	if (rate < VC5_PLL_VCO_MIN)
439		rate = VC5_PLL_VCO_MIN;
440	if (rate > VC5_PLL_VCO_MAX)
441		rate = VC5_PLL_VCO_MAX;
442
443	/* Determine integer part, which is 12 bit wide */
444	div_int = rate / *parent_rate;
445	if (div_int > 0xfff)
446		rate = *parent_rate * 0xfff;
447
448	/* Determine best fractional part, which is 24 bit wide */
449	div_frc = rate % *parent_rate;
450	div_frc *= BIT(24) - 1;
451	do_div(div_frc, *parent_rate);
452
453	hwdata->div_int = div_int;
454	hwdata->div_frc = (u32)div_frc;
455
456	return (*parent_rate * div_int) + ((*parent_rate * div_frc) >> 24);
457}
458
459static int vc5_pll_set_rate(struct clk_hw *hw, unsigned long rate,
460			    unsigned long parent_rate)
461{
462	struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
463	struct vc5_driver_data *vc5 = hwdata->vc5;
464	u8 fb[5];
465
466	fb[0] = hwdata->div_int >> 4;
467	fb[1] = hwdata->div_int << 4;
468	fb[2] = hwdata->div_frc >> 16;
469	fb[3] = hwdata->div_frc >> 8;
470	fb[4] = hwdata->div_frc;
471
472	return regmap_bulk_write(vc5->regmap, VC5_FEEDBACK_INT_DIV, fb, 5);
473}
474
475static const struct clk_ops vc5_pll_ops = {
476	.recalc_rate	= vc5_pll_recalc_rate,
477	.round_rate	= vc5_pll_round_rate,
478	.set_rate	= vc5_pll_set_rate,
479};
480
481static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw,
482					 unsigned long parent_rate)
483{
484	struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
485	struct vc5_driver_data *vc5 = hwdata->vc5;
486	/* VCO frequency is divided by two before entering FOD */
487	u32 f_in = parent_rate / 2;
488	u32 div_int, div_frc;
489	u8 od_int[2];
490	u8 od_frc[4];
491
492	regmap_bulk_read(vc5->regmap, VC5_OUT_DIV_INT(hwdata->num, 0),
493			 od_int, 2);
494	regmap_bulk_read(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
495			 od_frc, 4);
496
497	div_int = (od_int[0] << 4) | (od_int[1] >> 4);
498	div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) |
499		  (od_frc[2] << 6) | (od_frc[3] >> 2);
500
501	/* Avoid division by zero if the output is not configured. */
502	if (div_int == 0 && div_frc == 0)
503		return 0;
504
505	/* The PLL divider has 12 integer bits and 30 fractional bits */
506	return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
507}
508
509static long vc5_fod_round_rate(struct clk_hw *hw, unsigned long rate,
510			       unsigned long *parent_rate)
511{
512	struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
513	/* VCO frequency is divided by two before entering FOD */
514	u32 f_in = *parent_rate / 2;
515	u32 div_int;
516	u64 div_frc;
517
518	/* Determine integer part, which is 12 bit wide */
519	div_int = f_in / rate;
520	/*
521	 * WARNING: The clock chip does not output signal if the integer part
522	 *          of the divider is 0xfff and fractional part is non-zero.
523	 *          Clamp the divider at 0xffe to keep the code simple.
524	 */
525	if (div_int > 0xffe) {
526		div_int = 0xffe;
527		rate = f_in / div_int;
528	}
529
530	/* Determine best fractional part, which is 30 bit wide */
531	div_frc = f_in % rate;
532	div_frc <<= 24;
533	do_div(div_frc, rate);
534
535	hwdata->div_int = div_int;
536	hwdata->div_frc = (u32)div_frc;
537
538	return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
539}
540
541static int vc5_fod_set_rate(struct clk_hw *hw, unsigned long rate,
542			    unsigned long parent_rate)
543{
544	struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
545	struct vc5_driver_data *vc5 = hwdata->vc5;
546	u8 data[14] = {
547		hwdata->div_frc >> 22, hwdata->div_frc >> 14,
548		hwdata->div_frc >> 6, hwdata->div_frc << 2,
549		0, 0, 0, 0, 0,
550		0, 0,
551		hwdata->div_int >> 4, hwdata->div_int << 4,
552		0
553	};
554
555	regmap_bulk_write(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
556			  data, 14);
557
558	/*
559	 * Toggle magic bit in undocumented register for unknown reason.
560	 * This is what the IDT timing commander tool does and the chip
561	 * datasheet somewhat implies this is needed, but the register
562	 * and the bit is not documented.
563	 */
564	regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
565			   VC5_GLOBAL_REGISTER_GLOBAL_RESET, 0);
566	regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
567			   VC5_GLOBAL_REGISTER_GLOBAL_RESET,
568			   VC5_GLOBAL_REGISTER_GLOBAL_RESET);
569	return 0;
570}
571
572static const struct clk_ops vc5_fod_ops = {
573	.recalc_rate	= vc5_fod_recalc_rate,
574	.round_rate	= vc5_fod_round_rate,
575	.set_rate	= vc5_fod_set_rate,
576};
577
578static int vc5_clk_out_prepare(struct clk_hw *hw)
579{
580	struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
581	struct vc5_driver_data *vc5 = hwdata->vc5;
582	const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
583			VC5_OUT_DIV_CONTROL_SEL_EXT |
584			VC5_OUT_DIV_CONTROL_EN_FOD;
585	unsigned int src;
586	int ret;
587
588	/*
589	 * When enabling a FOD, all currently enabled FODs are briefly
590	 * stopped in order to synchronize all of them. This causes a clock
591	 * disruption to any unrelated chips that might be already using
592	 * other clock outputs. Bypass the sync feature to avoid the issue,
593	 * which is possible on the VersaClock 6E family via reserved
594	 * registers.
595	 */
596	if (vc5->chip_info->flags & VC5_HAS_BYPASS_SYNC_BIT) {
597		ret = regmap_update_bits(vc5->regmap,
598					 VC5_RESERVED_X0(hwdata->num),
599					 VC5_RESERVED_X0_BYPASS_SYNC,
600					 VC5_RESERVED_X0_BYPASS_SYNC);
601		if (ret)
602			return ret;
603	}
604
605	/*
606	 * If the input mux is disabled, enable it first and
607	 * select source from matching FOD.
608	 */
609	regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
610	if ((src & mask) == 0) {
611		src = VC5_OUT_DIV_CONTROL_RESET | VC5_OUT_DIV_CONTROL_EN_FOD;
612		ret = regmap_update_bits(vc5->regmap,
613					 VC5_OUT_DIV_CONTROL(hwdata->num),
614					 mask | VC5_OUT_DIV_CONTROL_RESET, src);
615		if (ret)
616			return ret;
617	}
618
619	/* Enable the clock buffer */
620	regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
621			   VC5_CLK_OUTPUT_CFG1_EN_CLKBUF,
622			   VC5_CLK_OUTPUT_CFG1_EN_CLKBUF);
623	if (hwdata->clk_output_cfg0_mask) {
624		dev_dbg(&vc5->client->dev, "Update output %d mask 0x%0X val 0x%0X\n",
625			hwdata->num, hwdata->clk_output_cfg0_mask,
626			hwdata->clk_output_cfg0);
627
628		regmap_update_bits(vc5->regmap,
629			VC5_CLK_OUTPUT_CFG(hwdata->num, 0),
630			hwdata->clk_output_cfg0_mask,
631			hwdata->clk_output_cfg0);
632	}
633
634	return 0;
635}
636
637static void vc5_clk_out_unprepare(struct clk_hw *hw)
638{
639	struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
640	struct vc5_driver_data *vc5 = hwdata->vc5;
641
642	/* Disable the clock buffer */
643	regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
644			   VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0);
645}
646
647static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
648{
649	struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
650	struct vc5_driver_data *vc5 = hwdata->vc5;
651	const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
652			VC5_OUT_DIV_CONTROL_SEL_EXT |
653			VC5_OUT_DIV_CONTROL_EN_FOD;
654	const u8 fodclkmask = VC5_OUT_DIV_CONTROL_SELB_NORM |
655			      VC5_OUT_DIV_CONTROL_EN_FOD;
656	const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
657			  VC5_OUT_DIV_CONTROL_SEL_EXT;
658	unsigned int src;
659
660	regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
661	src &= mask;
662
663	if (src == 0)	/* Input mux set to DISABLED */
664		return 0;
665
666	if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD)
667		return 0;
668
669	if (src == extclk)
670		return 1;
671
672	dev_warn(&vc5->client->dev,
673		 "Invalid clock output configuration (%02x)\n", src);
674	return 0;
675}
676
677static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index)
678{
679	struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
680	struct vc5_driver_data *vc5 = hwdata->vc5;
681	const u8 mask = VC5_OUT_DIV_CONTROL_RESET |
682			VC5_OUT_DIV_CONTROL_SELB_NORM |
683			VC5_OUT_DIV_CONTROL_SEL_EXT |
684			VC5_OUT_DIV_CONTROL_EN_FOD;
685	const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
686			  VC5_OUT_DIV_CONTROL_SEL_EXT;
687	u8 src = VC5_OUT_DIV_CONTROL_RESET;
688
689	if (index == 0)
690		src |= VC5_OUT_DIV_CONTROL_EN_FOD;
691	else
692		src |= extclk;
693
694	return regmap_update_bits(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num),
695				  mask, src);
696}
697
698static const struct clk_ops vc5_clk_out_ops = {
699	.prepare	= vc5_clk_out_prepare,
700	.unprepare	= vc5_clk_out_unprepare,
701	.set_parent	= vc5_clk_out_set_parent,
702	.get_parent	= vc5_clk_out_get_parent,
703};
704
705static struct clk_hw *vc5_of_clk_get(struct of_phandle_args *clkspec,
706				     void *data)
707{
708	struct vc5_driver_data *vc5 = data;
709	unsigned int idx = clkspec->args[0];
710
711	if (idx >= vc5->chip_info->clk_out_cnt)
712		return ERR_PTR(-EINVAL);
713
714	return &vc5->clk_out[idx].hw;
715}
716
717static int vc5_map_index_to_output(const enum vc5_model model,
718				   const unsigned int n)
719{
720	switch (model) {
721	case IDT_VC5_5P49V5933:
722		return (n == 0) ? 0 : 3;
723	case IDT_VC5_5P49V5923:
724	case IDT_VC5_5P49V5925:
725	case IDT_VC5_5P49V5935:
726	case IDT_VC6_5P49V6901:
727	case IDT_VC6_5P49V6965:
728	default:
729		return n;
730	}
731}
732
733static int vc5_update_mode(struct device_node *np_output,
734			   struct vc5_out_data *clk_out)
735{
736	u32 value;
737
738	if (!of_property_read_u32(np_output, "idt,mode", &value)) {
739		clk_out->clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_CFG_MASK;
740		switch (value) {
741		case VC5_CLK_OUTPUT_CFG0_CFG_LVPECL:
742		case VC5_CLK_OUTPUT_CFG0_CFG_CMOS:
743		case VC5_CLK_OUTPUT_CFG0_CFG_HCSL33:
744		case VC5_CLK_OUTPUT_CFG0_CFG_LVDS:
745		case VC5_CLK_OUTPUT_CFG0_CFG_CMOS2:
746		case VC5_CLK_OUTPUT_CFG0_CFG_CMOSD:
747		case VC5_CLK_OUTPUT_CFG0_CFG_HCSL25:
748			clk_out->clk_output_cfg0 |=
749			    value << VC5_CLK_OUTPUT_CFG0_CFG_SHIFT;
750			break;
751		default:
752			return -EINVAL;
753		}
754	}
755	return 0;
756}
757
758static int vc5_update_power(struct device_node *np_output,
759			    struct vc5_out_data *clk_out)
760{
761	u32 value;
762
763	if (!of_property_read_u32(np_output, "idt,voltage-microvolt",
764				  &value)) {
765		clk_out->clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_PWR_MASK;
766		switch (value) {
767		case 1800000:
768			clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_18;
769			break;
770		case 2500000:
771			clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_25;
772			break;
773		case 3300000:
774			clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_33;
775			break;
776		default:
777			return -EINVAL;
778		}
779	}
780	return 0;
781}
782
783static int vc5_update_slew(struct device_node *np_output,
784			   struct vc5_out_data *clk_out)
785{
786	u32 value;
787
788	if (!of_property_read_u32(np_output, "idt,slew-percent", &value)) {
789		clk_out->clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_SLEW_MASK;
790		switch (value) {
791		case 80:
792			clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_80;
793			break;
794		case 85:
795			clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_85;
796			break;
797		case 90:
798			clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_90;
799			break;
800		case 100:
801			clk_out->clk_output_cfg0 |=
802			    VC5_CLK_OUTPUT_CFG0_SLEW_100;
803			break;
804		default:
805			return -EINVAL;
806		}
807	}
808	return 0;
809}
810
811static int vc5_get_output_config(struct i2c_client *client,
812				 struct vc5_out_data *clk_out)
813{
814	struct device_node *np_output;
815	char *child_name;
816	int ret = 0;
817
818	child_name = kasprintf(GFP_KERNEL, "OUT%d", clk_out->num + 1);
819	if (!child_name)
820		return -ENOMEM;
821
822	np_output = of_get_child_by_name(client->dev.of_node, child_name);
823	kfree(child_name);
824	if (!np_output)
825		return 0;
826
827	ret = vc5_update_mode(np_output, clk_out);
828	if (ret)
829		goto output_error;
830
831	ret = vc5_update_power(np_output, clk_out);
832	if (ret)
833		goto output_error;
834
835	ret = vc5_update_slew(np_output, clk_out);
836
837output_error:
838	if (ret) {
839		dev_err(&client->dev,
840			"Invalid clock output configuration OUT%d\n",
841			clk_out->num + 1);
842	}
843
844	of_node_put(np_output);
845
846	return ret;
847}
848
849static const struct of_device_id clk_vc5_of_match[];
850
851static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
852{
853	struct vc5_driver_data *vc5;
854	struct clk_init_data init;
855	const char *parent_names[2];
856	unsigned int n, idx = 0;
857	int ret;
858
859	vc5 = devm_kzalloc(&client->dev, sizeof(*vc5), GFP_KERNEL);
860	if (!vc5)
861		return -ENOMEM;
862
863	i2c_set_clientdata(client, vc5);
864	vc5->client = client;
865	vc5->chip_info = of_device_get_match_data(&client->dev);
866
867	vc5->pin_xin = devm_clk_get(&client->dev, "xin");
868	if (PTR_ERR(vc5->pin_xin) == -EPROBE_DEFER)
869		return -EPROBE_DEFER;
870
871	vc5->pin_clkin = devm_clk_get(&client->dev, "clkin");
872	if (PTR_ERR(vc5->pin_clkin) == -EPROBE_DEFER)
873		return -EPROBE_DEFER;
874
875	vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config);
876	if (IS_ERR(vc5->regmap)) {
877		dev_err(&client->dev, "failed to allocate register map\n");
878		return PTR_ERR(vc5->regmap);
879	}
880
881	/* Register clock input mux */
882	memset(&init, 0, sizeof(init));
883
884	if (!IS_ERR(vc5->pin_xin)) {
885		vc5->clk_mux_ins |= VC5_MUX_IN_XIN;
886		parent_names[init.num_parents++] = __clk_get_name(vc5->pin_xin);
887	} else if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL) {
888		vc5->pin_xin = clk_register_fixed_rate(&client->dev,
889						       "internal-xtal", NULL,
890						       0, 25000000);
891		if (IS_ERR(vc5->pin_xin))
892			return PTR_ERR(vc5->pin_xin);
893		vc5->clk_mux_ins |= VC5_MUX_IN_XIN;
894		parent_names[init.num_parents++] = __clk_get_name(vc5->pin_xin);
895	}
896
897	if (!IS_ERR(vc5->pin_clkin)) {
898		vc5->clk_mux_ins |= VC5_MUX_IN_CLKIN;
899		parent_names[init.num_parents++] =
900		    __clk_get_name(vc5->pin_clkin);
901	}
902
903	if (!init.num_parents) {
904		dev_err(&client->dev, "no input clock specified!\n");
905		return -EINVAL;
906	}
907
908	init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node);
909	if (!init.name) {
910		ret = -ENOMEM;
911		goto err_clk;
912	}
913
914	init.ops = &vc5_mux_ops;
915	init.flags = 0;
916	init.parent_names = parent_names;
917	vc5->clk_mux.init = &init;
918	ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux);
919	if (ret)
920		goto err_clk_register;
921	kfree(init.name);	/* clock framework made a copy of the name */
922
923	if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) {
924		/* Register frequency doubler */
925		memset(&init, 0, sizeof(init));
926		init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl",
927				      client->dev.of_node);
928		if (!init.name) {
929			ret = -ENOMEM;
930			goto err_clk;
931		}
932		init.ops = &vc5_dbl_ops;
933		init.flags = CLK_SET_RATE_PARENT;
934		init.parent_names = parent_names;
935		parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
936		init.num_parents = 1;
937		vc5->clk_mul.init = &init;
938		ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul);
939		if (ret)
940			goto err_clk_register;
941		kfree(init.name); /* clock framework made a copy of the name */
942	}
943
944	/* Register PFD */
945	memset(&init, 0, sizeof(init));
946	init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node);
947	if (!init.name) {
948		ret = -ENOMEM;
949		goto err_clk;
950	}
951	init.ops = &vc5_pfd_ops;
952	init.flags = CLK_SET_RATE_PARENT;
953	init.parent_names = parent_names;
954	if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL)
955		parent_names[0] = clk_hw_get_name(&vc5->clk_mul);
956	else
957		parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
958	init.num_parents = 1;
959	vc5->clk_pfd.init = &init;
960	ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd);
961	if (ret)
962		goto err_clk_register;
963	kfree(init.name);	/* clock framework made a copy of the name */
964
965	/* Register PLL */
966	memset(&init, 0, sizeof(init));
967	init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node);
968	if (!init.name) {
969		ret = -ENOMEM;
970		goto err_clk;
971	}
972	init.ops = &vc5_pll_ops;
973	init.flags = CLK_SET_RATE_PARENT;
974	init.parent_names = parent_names;
975	parent_names[0] = clk_hw_get_name(&vc5->clk_pfd);
976	init.num_parents = 1;
977	vc5->clk_pll.num = 0;
978	vc5->clk_pll.vc5 = vc5;
979	vc5->clk_pll.hw.init = &init;
980	ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw);
981	if (ret)
982		goto err_clk_register;
983	kfree(init.name); /* clock framework made a copy of the name */
984
985	/* Register FODs */
986	for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
987		idx = vc5_map_index_to_output(vc5->chip_info->model, n);
988		memset(&init, 0, sizeof(init));
989		init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d",
990				      client->dev.of_node, idx);
991		if (!init.name) {
992			ret = -ENOMEM;
993			goto err_clk;
994		}
995		init.ops = &vc5_fod_ops;
996		init.flags = CLK_SET_RATE_PARENT;
997		init.parent_names = parent_names;
998		parent_names[0] = clk_hw_get_name(&vc5->clk_pll.hw);
999		init.num_parents = 1;
1000		vc5->clk_fod[n].num = idx;
1001		vc5->clk_fod[n].vc5 = vc5;
1002		vc5->clk_fod[n].hw.init = &init;
1003		ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw);
1004		if (ret)
1005			goto err_clk_register;
1006		kfree(init.name); /* clock framework made a copy of the name */
1007	}
1008
1009	/* Register MUX-connected OUT0_I2C_SELB output */
1010	memset(&init, 0, sizeof(init));
1011	init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb",
1012			      client->dev.of_node);
1013	if (!init.name) {
1014		ret = -ENOMEM;
1015		goto err_clk;
1016	}
1017	init.ops = &vc5_clk_out_ops;
1018	init.flags = CLK_SET_RATE_PARENT;
1019	init.parent_names = parent_names;
1020	parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
1021	init.num_parents = 1;
1022	vc5->clk_out[0].num = idx;
1023	vc5->clk_out[0].vc5 = vc5;
1024	vc5->clk_out[0].hw.init = &init;
1025	ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw);
1026	if (ret)
1027		goto err_clk_register;
1028	kfree(init.name); /* clock framework made a copy of the name */
1029
1030	/* Register FOD-connected OUTx outputs */
1031	for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
1032		idx = vc5_map_index_to_output(vc5->chip_info->model, n - 1);
1033		parent_names[0] = clk_hw_get_name(&vc5->clk_fod[idx].hw);
1034		if (n == 1)
1035			parent_names[1] = clk_hw_get_name(&vc5->clk_mux);
1036		else
1037			parent_names[1] =
1038			    clk_hw_get_name(&vc5->clk_out[n - 1].hw);
1039
1040		memset(&init, 0, sizeof(init));
1041		init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d",
1042				      client->dev.of_node, idx + 1);
1043		if (!init.name) {
1044			ret = -ENOMEM;
1045			goto err_clk;
1046		}
1047		init.ops = &vc5_clk_out_ops;
1048		init.flags = CLK_SET_RATE_PARENT;
1049		init.parent_names = parent_names;
1050		init.num_parents = 2;
1051		vc5->clk_out[n].num = idx;
1052		vc5->clk_out[n].vc5 = vc5;
1053		vc5->clk_out[n].hw.init = &init;
1054		ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[n].hw);
1055		if (ret)
1056			goto err_clk_register;
1057		kfree(init.name); /* clock framework made a copy of the name */
1058
1059		/* Fetch Clock Output configuration from DT (if specified) */
1060		ret = vc5_get_output_config(client, &vc5->clk_out[n]);
1061		if (ret)
1062			goto err_clk;
1063	}
1064
1065	ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5);
1066	if (ret) {
1067		dev_err(&client->dev, "unable to add clk provider\n");
1068		goto err_clk;
1069	}
1070
1071	return 0;
1072
1073err_clk_register:
1074	dev_err(&client->dev, "unable to register %s\n", init.name);
1075	kfree(init.name); /* clock framework made a copy of the name */
1076err_clk:
1077	if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
1078		clk_unregister_fixed_rate(vc5->pin_xin);
1079	return ret;
1080}
1081
1082static int vc5_remove(struct i2c_client *client)
1083{
1084	struct vc5_driver_data *vc5 = i2c_get_clientdata(client);
1085
1086	of_clk_del_provider(client->dev.of_node);
1087
1088	if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
1089		clk_unregister_fixed_rate(vc5->pin_xin);
1090
1091	return 0;
1092}
1093
1094static int __maybe_unused vc5_suspend(struct device *dev)
1095{
1096	struct vc5_driver_data *vc5 = dev_get_drvdata(dev);
1097
1098	regcache_cache_only(vc5->regmap, true);
1099	regcache_mark_dirty(vc5->regmap);
1100
1101	return 0;
1102}
1103
1104static int __maybe_unused vc5_resume(struct device *dev)
1105{
1106	struct vc5_driver_data *vc5 = dev_get_drvdata(dev);
1107	int ret;
1108
1109	regcache_cache_only(vc5->regmap, false);
1110	ret = regcache_sync(vc5->regmap);
1111	if (ret)
1112		dev_err(dev, "Failed to restore register map: %d\n", ret);
1113	return ret;
1114}
1115
1116static const struct vc5_chip_info idt_5p49v5923_info = {
1117	.model = IDT_VC5_5P49V5923,
1118	.clk_fod_cnt = 2,
1119	.clk_out_cnt = 3,
1120	.flags = 0,
1121};
1122
1123static const struct vc5_chip_info idt_5p49v5925_info = {
1124	.model = IDT_VC5_5P49V5925,
1125	.clk_fod_cnt = 4,
1126	.clk_out_cnt = 5,
1127	.flags = 0,
1128};
1129
1130static const struct vc5_chip_info idt_5p49v5933_info = {
1131	.model = IDT_VC5_5P49V5933,
1132	.clk_fod_cnt = 2,
1133	.clk_out_cnt = 3,
1134	.flags = VC5_HAS_INTERNAL_XTAL,
1135};
1136
1137static const struct vc5_chip_info idt_5p49v5935_info = {
1138	.model = IDT_VC5_5P49V5935,
1139	.clk_fod_cnt = 4,
1140	.clk_out_cnt = 5,
1141	.flags = VC5_HAS_INTERNAL_XTAL,
1142};
1143
1144static const struct vc5_chip_info idt_5p49v6901_info = {
1145	.model = IDT_VC6_5P49V6901,
1146	.clk_fod_cnt = 4,
1147	.clk_out_cnt = 5,
1148	.flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT,
1149};
1150
1151static const struct vc5_chip_info idt_5p49v6965_info = {
1152	.model = IDT_VC6_5P49V6965,
1153	.clk_fod_cnt = 4,
1154	.clk_out_cnt = 5,
1155	.flags = VC5_HAS_BYPASS_SYNC_BIT,
1156};
1157
1158static const struct i2c_device_id vc5_id[] = {
1159	{ "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
1160	{ "5p49v5925", .driver_data = IDT_VC5_5P49V5925 },
1161	{ "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
1162	{ "5p49v5935", .driver_data = IDT_VC5_5P49V5935 },
1163	{ "5p49v6901", .driver_data = IDT_VC6_5P49V6901 },
1164	{ "5p49v6965", .driver_data = IDT_VC6_5P49V6965 },
1165	{ }
1166};
1167MODULE_DEVICE_TABLE(i2c, vc5_id);
1168
1169static const struct of_device_id clk_vc5_of_match[] = {
1170	{ .compatible = "idt,5p49v5923", .data = &idt_5p49v5923_info },
1171	{ .compatible = "idt,5p49v5925", .data = &idt_5p49v5925_info },
1172	{ .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info },
1173	{ .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info },
1174	{ .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info },
1175	{ .compatible = "idt,5p49v6965", .data = &idt_5p49v6965_info },
1176	{ },
1177};
1178MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
1179
1180static SIMPLE_DEV_PM_OPS(vc5_pm_ops, vc5_suspend, vc5_resume);
1181
1182static struct i2c_driver vc5_driver = {
1183	.driver = {
1184		.name = "vc5",
1185		.pm	= &vc5_pm_ops,
1186		.of_match_table = clk_vc5_of_match,
1187	},
1188	.probe		= vc5_probe,
1189	.remove		= vc5_remove,
1190	.id_table	= vc5_id,
1191};
1192module_i2c_driver(vc5_driver);
1193
1194MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
1195MODULE_DESCRIPTION("IDT VersaClock 5 driver");
1196MODULE_LICENSE("GPL");
1197