blob: aec375690543ee1e06dde197f50bbd2ee7d8cfef [file] [log] [blame]
Nageswari Srinivasan5b8972d2010-01-06 17:19:48 +05301/*
2 * TI CDCE949 clock synthesizer driver
3 *
4 * Note: This implementation assumes an input of 27MHz to the CDCE.
5 * This is by no means constrained by CDCE hardware although the datasheet
6 * does use this as an example for all illustrations and more importantly:
7 * that is the crystal input on boards it is currently used on.
8 *
9 * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16#include <linux/kernel.h>
17#include <linux/clk.h>
18#include <linux/platform_device.h>
19#include <linux/i2c.h>
20
21#include <mach/clock.h>
22
23#include "clock.h"
24
25static struct i2c_client *cdce_i2c_client;
Sekhar Nori3b43cd62010-01-12 18:55:35 +053026static DEFINE_MUTEX(cdce_mutex);
Nageswari Srinivasan5b8972d2010-01-06 17:19:48 +053027
28/* CDCE register descriptor */
29struct cdce_reg {
30 u8 addr;
31 u8 val;
32};
33
34/* Per-Output (Y1, Y2 etc.) frequency descriptor */
35struct cdce_freq {
36 /* Frequency in KHz */
37 unsigned long frequency;
38 /*
39 * List of registers to program to obtain a particular frequency.
40 * 0x0 in register address and value is the end of list marker.
41 */
42 struct cdce_reg *reglist;
43};
44
45#define CDCE_FREQ_TABLE_ENTRY(line, out) \
46{ \
47 .reglist = cdce_y ##line## _ ##out, \
48 .frequency = out, \
49}
50
51/* List of CDCE outputs */
52struct cdce_output {
53 /* List of frequencies on this output */
54 struct cdce_freq *freq_table;
55 /* Number of possible frequencies */
56 int size;
57};
58
59/*
60 * Finding out the values to program into CDCE949 registers for a particular
61 * frequency output is not a simple calculation. Have a look at the datasheet
62 * for the details. There is desktop software available to help users with
63 * the calculations. Here, we just depend on the output of that software
64 * (or hand calculations) instead trying to runtime calculate the register
65 * values and inflicting misery on ourselves.
66 */
67static struct cdce_reg cdce_y1_148500[] = {
68 { 0x13, 0x00 },
69 /* program PLL1_0 multiplier */
70 { 0x18, 0xaf },
71 { 0x19, 0x50 },
72 { 0x1a, 0x02 },
73 { 0x1b, 0xc9 },
74 /* program PLL1_11 multiplier */
75 { 0x1c, 0x00 },
76 { 0x1d, 0x40 },
77 { 0x1e, 0x02 },
78 { 0x1f, 0xc9 },
79 /* output state selection */
80 { 0x15, 0x00 },
81 { 0x14, 0xef },
82 /* switch MUX to PLL1 output */
83 { 0x14, 0x6f },
84 { 0x16, 0x06 },
85 /* set P2DIV divider, P3DIV and input crystal */
86 { 0x17, 0x06 },
87 { 0x01, 0x00 },
88 { 0x05, 0x48 },
89 { 0x02, 0x80 },
90 /* enable and disable PLL */
91 { 0x02, 0xbc },
92 { 0x03, 0x01 },
93 { },
94};
95
96static struct cdce_reg cdce_y1_74250[] = {
97 { 0x13, 0x00 },
98 { 0x18, 0xaf },
99 { 0x19, 0x50 },
100 { 0x1a, 0x02 },
101 { 0x1b, 0xc9 },
102 { 0x1c, 0x00 },
103 { 0x1d, 0x40 },
104 { 0x1e, 0x02 },
105 { 0x1f, 0xc9 },
106 /* output state selection */
107 { 0x15, 0x00 },
108 { 0x14, 0xef },
109 /* switch MUX to PLL1 output */
110 { 0x14, 0x6f },
111 { 0x16, 0x06 },
112 /* set P2DIV divider, P3DIV and input crystal */
113 { 0x17, 0x06 },
114 { 0x01, 0x00 },
115 { 0x05, 0x48 },
116 { 0x02, 0x80 },
117 /* enable and disable PLL */
118 { 0x02, 0xbc },
119 { 0x03, 0x02 },
120 { },
121};
122
123static struct cdce_reg cdce_y1_27000[] = {
124 { 0x13, 0x00 },
125 { 0x18, 0x00 },
126 { 0x19, 0x40 },
127 { 0x1a, 0x02 },
128 { 0x1b, 0x08 },
129 { 0x1c, 0x00 },
130 { 0x1d, 0x40 },
131 { 0x1e, 0x02 },
132 { 0x1f, 0x08 },
133 { 0x15, 0x02 },
134 { 0x14, 0xed },
135 { 0x16, 0x01 },
136 { 0x17, 0x01 },
137 { 0x01, 0x00 },
138 { 0x05, 0x50 },
139 { 0x02, 0xb4 },
140 { 0x03, 0x01 },
141 { },
142};
143
144static struct cdce_freq cdce_y1_freqs[] = {
145 CDCE_FREQ_TABLE_ENTRY(1, 148500),
146 CDCE_FREQ_TABLE_ENTRY(1, 74250),
147 CDCE_FREQ_TABLE_ENTRY(1, 27000),
148};
149
150static struct cdce_reg cdce_y5_13500[] = {
151 { 0x27, 0x08 },
152 { 0x28, 0x00 },
153 { 0x29, 0x40 },
154 { 0x2a, 0x02 },
155 { 0x2b, 0x08 },
156 { 0x24, 0x6f },
157 { },
158};
159
160static struct cdce_reg cdce_y5_16875[] = {
161 { 0x27, 0x08 },
162 { 0x28, 0x9f },
163 { 0x29, 0xb0 },
164 { 0x2a, 0x02 },
165 { 0x2b, 0x89 },
166 { 0x24, 0x6f },
167 { },
168};
169
170static struct cdce_reg cdce_y5_27000[] = {
171 { 0x27, 0x04 },
172 { 0x28, 0x00 },
173 { 0x29, 0x40 },
174 { 0x2a, 0x02 },
175 { 0x2b, 0x08 },
176 { 0x24, 0x6f },
177 { },
178};
179static struct cdce_reg cdce_y5_54000[] = {
180 { 0x27, 0x04 },
181 { 0x28, 0xff },
182 { 0x29, 0x80 },
183 { 0x2a, 0x02 },
184 { 0x2b, 0x07 },
185 { 0x24, 0x6f },
186 { },
187};
188
189static struct cdce_reg cdce_y5_81000[] = {
190 { 0x27, 0x02 },
191 { 0x28, 0xbf },
192 { 0x29, 0xa0 },
193 { 0x2a, 0x03 },
194 { 0x2b, 0x0a },
195 { 0x24, 0x6f },
196 { },
197};
198
199static struct cdce_freq cdce_y5_freqs[] = {
200 CDCE_FREQ_TABLE_ENTRY(5, 13500),
201 CDCE_FREQ_TABLE_ENTRY(5, 16875),
202 CDCE_FREQ_TABLE_ENTRY(5, 27000),
203 CDCE_FREQ_TABLE_ENTRY(5, 54000),
204 CDCE_FREQ_TABLE_ENTRY(5, 81000),
205};
206
207
208static struct cdce_output output_list[] = {
209 [1] = { cdce_y1_freqs, ARRAY_SIZE(cdce_y1_freqs) },
210 [5] = { cdce_y5_freqs, ARRAY_SIZE(cdce_y5_freqs) },
211};
212
213int cdce_set_rate(struct clk *clk, unsigned long rate)
214{
215 int i, ret = 0;
216 struct cdce_freq *freq_table = output_list[clk->lpsc].freq_table;
217 struct cdce_reg *regs = NULL;
218
219 if (!cdce_i2c_client)
220 return -ENODEV;
221
222 if (!freq_table)
223 return -EINVAL;
224
225 for (i = 0; i < output_list[clk->lpsc].size; i++) {
226 if (freq_table[i].frequency == rate / 1000) {
227 regs = freq_table[i].reglist;
228 break;
229 }
230 }
231
232 if (!regs)
233 return -EINVAL;
234
Sekhar Nori3b43cd62010-01-12 18:55:35 +0530235 mutex_lock(&cdce_mutex);
Nageswari Srinivasan5b8972d2010-01-06 17:19:48 +0530236 for (i = 0; regs[i].addr; i++) {
237 ret = i2c_smbus_write_byte_data(cdce_i2c_client,
238 regs[i].addr | 0x80, regs[i].val);
239 if (ret)
Sekhar Nori3b43cd62010-01-12 18:55:35 +0530240 break;
Nageswari Srinivasan5b8972d2010-01-06 17:19:48 +0530241 }
Sekhar Nori3b43cd62010-01-12 18:55:35 +0530242 mutex_unlock(&cdce_mutex);
Nageswari Srinivasan5b8972d2010-01-06 17:19:48 +0530243
Sekhar Nori3b43cd62010-01-12 18:55:35 +0530244 if (!ret)
245 clk->rate = rate;
Nageswari Srinivasan5b8972d2010-01-06 17:19:48 +0530246
Sekhar Nori3b43cd62010-01-12 18:55:35 +0530247 return ret;
Nageswari Srinivasan5b8972d2010-01-06 17:19:48 +0530248}
249
250static int cdce_probe(struct i2c_client *client,
251 const struct i2c_device_id *id)
252{
253 cdce_i2c_client = client;
254 return 0;
255}
256
257static int __devexit cdce_remove(struct i2c_client *client)
258{
259 cdce_i2c_client = NULL;
260 return 0;
261}
262
263static const struct i2c_device_id cdce_id[] = {
264 {"cdce949", 0},
265 {},
266};
267MODULE_DEVICE_TABLE(i2c, cdce_id);
268
269static struct i2c_driver cdce_driver = {
270 .driver = {
271 .owner = THIS_MODULE,
272 .name = "cdce949",
273 },
274 .probe = cdce_probe,
275 .remove = __devexit_p(cdce_remove),
276 .id_table = cdce_id,
277};
278
279static int __init cdce_init(void)
280{
281 return i2c_add_driver(&cdce_driver);
282}
283subsys_initcall(cdce_init);
284
285static void __exit cdce_exit(void)
286{
287 i2c_del_driver(&cdce_driver);
288}
289module_exit(cdce_exit);
290
291MODULE_AUTHOR("Texas Instruments");
292MODULE_DESCRIPTION("CDCE949 clock synthesizer driver");
293MODULE_LICENSE("GPL v2");