16
16
#include <linux/slab.h>
17
17
#include <asm/unaligned.h>
18
18
19
+ #define SI5341_NUM_INPUTS 4
20
+
19
21
#define SI5341_MAX_NUM_OUTPUTS 10
20
22
#define SI5340_MAX_NUM_OUTPUTS 4
21
23
@@ -56,8 +58,8 @@ struct clk_si5341 {
56
58
struct i2c_client * i2c_client ;
57
59
struct clk_si5341_synth synth [SI5341_NUM_SYNTH ];
58
60
struct clk_si5341_output clk [SI5341_MAX_NUM_OUTPUTS ];
59
- struct clk * pxtal ;
60
- const char * pxtal_name ;
61
+ struct clk * input_clk [ SI5341_NUM_INPUTS ] ;
62
+ const char * input_clk_name [ SI5341_NUM_INPUTS ] ;
61
63
const u16 * reg_output_offset ;
62
64
const u16 * reg_rdiv_offset ;
63
65
u64 freq_vco ; /* 13500–14256 MHz */
@@ -78,10 +80,25 @@ struct clk_si5341_output_config {
78
80
#define SI5341_DEVICE_REV 0x0005
79
81
#define SI5341_STATUS 0x000C
80
82
#define SI5341_SOFT_RST 0x001C
83
+ #define SI5341_IN_SEL 0x0021
84
+ #define SI5341_XAXB_CFG 0x090E
85
+ #define SI5341_IN_EN 0x0949
86
+ #define SI5341_INX_TO_PFD_EN 0x094A
87
+
88
+ /* Input selection */
89
+ #define SI5341_IN_SEL_MASK 0x06
90
+ #define SI5341_IN_SEL_SHIFT 1
91
+ #define SI5341_IN_SEL_REGCTRL 0x01
92
+ #define SI5341_INX_TO_PFD_SHIFT 4
93
+
94
+ /* XTAL config bits */
95
+ #define SI5341_XAXB_CFG_EXTCLK_EN BIT(0)
96
+ #define SI5341_XAXB_CFG_PDNB BIT(1)
81
97
82
98
/* Input dividers (48-bit) */
83
99
#define SI5341_IN_PDIV (x ) (0x0208 + ((x) * 10))
84
100
#define SI5341_IN_PSET (x ) (0x020E + ((x) * 10))
101
+ #define SI5341_PX_UPD 0x0230
85
102
86
103
/* PLL configuration */
87
104
#define SI5341_PLL_M_NUM 0x0235
@@ -120,6 +137,10 @@ struct si5341_reg_default {
120
137
u8 value ;
121
138
};
122
139
140
+ static const char * const si5341_input_clock_names [] = {
141
+ "in0" , "in1" , "in2" , "xtal"
142
+ };
143
+
123
144
/* Output configuration registers 0..9 are not quite logically organized */
124
145
static const u16 si5341_reg_output_offset [] = {
125
146
0x0108 ,
@@ -390,7 +411,112 @@ static unsigned long si5341_clk_recalc_rate(struct clk_hw *hw,
390
411
return (unsigned long )res ;
391
412
}
392
413
414
+ static int si5341_clk_get_selected_input (struct clk_si5341 * data )
415
+ {
416
+ int err ;
417
+ u32 val ;
418
+
419
+ err = regmap_read (data -> regmap , SI5341_IN_SEL , & val );
420
+ if (err < 0 )
421
+ return err ;
422
+
423
+ return (val & SI5341_IN_SEL_MASK ) >> SI5341_IN_SEL_SHIFT ;
424
+ }
425
+
426
+ static u8 si5341_clk_get_parent (struct clk_hw * hw )
427
+ {
428
+ struct clk_si5341 * data = to_clk_si5341 (hw );
429
+ int res = si5341_clk_get_selected_input (data );
430
+
431
+ if (res < 0 )
432
+ return 0 ; /* Apparently we cannot report errors */
433
+
434
+ return res ;
435
+ }
436
+
437
+ static int si5341_clk_reparent (struct clk_si5341 * data , u8 index )
438
+ {
439
+ int err ;
440
+ u8 val ;
441
+
442
+ val = (index << SI5341_IN_SEL_SHIFT ) & SI5341_IN_SEL_MASK ;
443
+ /* Enable register-based input selection */
444
+ val |= SI5341_IN_SEL_REGCTRL ;
445
+
446
+ err = regmap_update_bits (data -> regmap ,
447
+ SI5341_IN_SEL , SI5341_IN_SEL_REGCTRL | SI5341_IN_SEL_MASK , val );
448
+ if (err < 0 )
449
+ return err ;
450
+
451
+ if (index < 3 ) {
452
+ /* Enable input buffer for selected input */
453
+ err = regmap_update_bits (data -> regmap ,
454
+ SI5341_IN_EN , 0x07 , BIT (index ));
455
+ if (err < 0 )
456
+ return err ;
457
+
458
+ /* Enables the input to phase detector */
459
+ err = regmap_update_bits (data -> regmap , SI5341_INX_TO_PFD_EN ,
460
+ 0x7 << SI5341_INX_TO_PFD_SHIFT ,
461
+ BIT (index + SI5341_INX_TO_PFD_SHIFT ));
462
+ if (err < 0 )
463
+ return err ;
464
+
465
+ /* Power down XTAL oscillator and buffer */
466
+ err = regmap_update_bits (data -> regmap , SI5341_XAXB_CFG ,
467
+ SI5341_XAXB_CFG_PDNB , 0 );
468
+ if (err < 0 )
469
+ return err ;
470
+
471
+ /*
472
+ * Set the P divider to "1". There's no explanation in the
473
+ * datasheet of these registers, but the clockbuilder software
474
+ * programs a "1" when the input is being used.
475
+ */
476
+ err = regmap_write (data -> regmap , SI5341_IN_PDIV (index ), 1 );
477
+ if (err < 0 )
478
+ return err ;
479
+
480
+ err = regmap_write (data -> regmap , SI5341_IN_PSET (index ), 1 );
481
+ if (err < 0 )
482
+ return err ;
483
+
484
+ /* Set update PDIV bit */
485
+ err = regmap_write (data -> regmap , SI5341_PX_UPD , BIT (index ));
486
+ if (err < 0 )
487
+ return err ;
488
+ } else {
489
+ /* Disable all input buffers */
490
+ err = regmap_update_bits (data -> regmap , SI5341_IN_EN , 0x07 , 0 );
491
+ if (err < 0 )
492
+ return err ;
493
+
494
+ /* Disable input to phase detector */
495
+ err = regmap_update_bits (data -> regmap , SI5341_INX_TO_PFD_EN ,
496
+ 0x7 << SI5341_INX_TO_PFD_SHIFT , 0 );
497
+ if (err < 0 )
498
+ return err ;
499
+
500
+ /* Power up XTAL oscillator and buffer */
501
+ err = regmap_update_bits (data -> regmap , SI5341_XAXB_CFG ,
502
+ SI5341_XAXB_CFG_PDNB , SI5341_XAXB_CFG_PDNB );
503
+ if (err < 0 )
504
+ return err ;
505
+ }
506
+
507
+ return 0 ;
508
+ }
509
+
510
+ static int si5341_clk_set_parent (struct clk_hw * hw , u8 index )
511
+ {
512
+ struct clk_si5341 * data = to_clk_si5341 (hw );
513
+
514
+ return si5341_clk_reparent (data , index );
515
+ }
516
+
393
517
static const struct clk_ops si5341_clk_ops = {
518
+ .set_parent = si5341_clk_set_parent ,
519
+ .get_parent = si5341_clk_get_parent ,
394
520
.recalc_rate = si5341_clk_recalc_rate ,
395
521
};
396
522
@@ -985,7 +1111,8 @@ static const struct regmap_range si5341_regmap_volatile_range[] = {
985
1111
regmap_reg_range (0x000C , 0x0012 ), /* Status */
986
1112
regmap_reg_range (0x001C , 0x001E ), /* reset, finc/fdec */
987
1113
regmap_reg_range (0x00E2 , 0x00FE ), /* NVM, interrupts, device ready */
988
- /* Update bits for synth config */
1114
+ /* Update bits for P divider and synth config */
1115
+ regmap_reg_range (SI5341_PX_UPD , SI5341_PX_UPD ),
989
1116
regmap_reg_range (SI5341_SYNTH_N_UPD (0 ), SI5341_SYNTH_N_UPD (0 )),
990
1117
regmap_reg_range (SI5341_SYNTH_N_UPD (1 ), SI5341_SYNTH_N_UPD (1 )),
991
1118
regmap_reg_range (SI5341_SYNTH_N_UPD (2 ), SI5341_SYNTH_N_UPD (2 )),
@@ -1122,6 +1249,7 @@ static int si5341_initialize_pll(struct clk_si5341 *data)
1122
1249
struct device_node * np = data -> i2c_client -> dev .of_node ;
1123
1250
u32 m_num = 0 ;
1124
1251
u32 m_den = 0 ;
1252
+ int sel ;
1125
1253
1126
1254
if (of_property_read_u32 (np , "silabs,pll-m-num" , & m_num )) {
1127
1255
dev_err (& data -> i2c_client -> dev ,
@@ -1135,19 +1263,64 @@ static int si5341_initialize_pll(struct clk_si5341 *data)
1135
1263
if (!m_num || !m_den ) {
1136
1264
dev_err (& data -> i2c_client -> dev ,
1137
1265
"PLL configuration invalid, assume 14GHz\n" );
1138
- m_den = clk_get_rate (data -> pxtal ) / 10 ;
1266
+ sel = si5341_clk_get_selected_input (data );
1267
+ if (sel < 0 )
1268
+ return sel ;
1269
+
1270
+ m_den = clk_get_rate (data -> input_clk [sel ]) / 10 ;
1139
1271
m_num = 1400000000 ;
1140
1272
}
1141
1273
1142
1274
return si5341_encode_44_32 (data -> regmap ,
1143
1275
SI5341_PLL_M_NUM , m_num , m_den );
1144
1276
}
1145
1277
1278
+ static int si5341_clk_select_active_input (struct clk_si5341 * data )
1279
+ {
1280
+ int res ;
1281
+ int err ;
1282
+ int i ;
1283
+
1284
+ res = si5341_clk_get_selected_input (data );
1285
+ if (res < 0 )
1286
+ return res ;
1287
+
1288
+ /* If the current register setting is invalid, pick the first input */
1289
+ if (!data -> input_clk [res ]) {
1290
+ dev_dbg (& data -> i2c_client -> dev ,
1291
+ "Input %d not connected, rerouting\n" , res );
1292
+ res = - ENODEV ;
1293
+ for (i = 0 ; i < SI5341_NUM_INPUTS ; ++ i ) {
1294
+ if (data -> input_clk [i ]) {
1295
+ res = i ;
1296
+ break ;
1297
+ }
1298
+ }
1299
+ if (res < 0 ) {
1300
+ dev_err (& data -> i2c_client -> dev ,
1301
+ "No clock input available\n" );
1302
+ return res ;
1303
+ }
1304
+ }
1305
+
1306
+ /* Make sure the selected clock is also enabled and routed */
1307
+ err = si5341_clk_reparent (data , res );
1308
+ if (err < 0 )
1309
+ return err ;
1310
+
1311
+ err = clk_prepare_enable (data -> input_clk [res ]);
1312
+ if (err < 0 )
1313
+ return err ;
1314
+
1315
+ return res ;
1316
+ }
1317
+
1146
1318
static int si5341_probe (struct i2c_client * client ,
1147
1319
const struct i2c_device_id * id )
1148
1320
{
1149
1321
struct clk_si5341 * data ;
1150
1322
struct clk_init_data init ;
1323
+ struct clk * input ;
1151
1324
const char * root_clock_name ;
1152
1325
const char * synth_clock_names [SI5341_NUM_SYNTH ];
1153
1326
int err ;
@@ -1161,12 +1334,16 @@ static int si5341_probe(struct i2c_client *client,
1161
1334
1162
1335
data -> i2c_client = client ;
1163
1336
1164
- data -> pxtal = devm_clk_get (& client -> dev , "xtal" );
1165
- if (IS_ERR (data -> pxtal )) {
1166
- if (PTR_ERR (data -> pxtal ) == - EPROBE_DEFER )
1167
- return - EPROBE_DEFER ;
1168
-
1169
- dev_err (& client -> dev , "Missing xtal clock input\n" );
1337
+ for (i = 0 ; i < SI5341_NUM_INPUTS ; ++ i ) {
1338
+ input = devm_clk_get (& client -> dev , si5341_input_clock_names [i ]);
1339
+ if (IS_ERR (input )) {
1340
+ if (PTR_ERR (input ) == - EPROBE_DEFER )
1341
+ return - EPROBE_DEFER ;
1342
+ data -> input_clk_name [i ] = si5341_input_clock_names [i ];
1343
+ } else {
1344
+ data -> input_clk [i ] = input ;
1345
+ data -> input_clk_name [i ] = __clk_get_name (input );
1346
+ }
1170
1347
}
1171
1348
1172
1349
err = si5341_dt_parse_dt (client , config );
@@ -1188,9 +1365,6 @@ static int si5341_probe(struct i2c_client *client,
1188
1365
if (err < 0 )
1189
1366
return err ;
1190
1367
1191
- /* "Activate" the xtal (usually a fixed clock) */
1192
- clk_prepare_enable (data -> pxtal );
1193
-
1194
1368
if (of_property_read_bool (client -> dev .of_node , "silabs,reprogram" )) {
1195
1369
initialization_required = true;
1196
1370
} else {
@@ -1223,17 +1397,23 @@ static int si5341_probe(struct i2c_client *client,
1223
1397
ARRAY_SIZE (si5341_reg_defaults ));
1224
1398
if (err < 0 )
1225
1399
return err ;
1400
+ }
1401
+
1402
+ /* Input must be up and running at this point */
1403
+ err = si5341_clk_select_active_input (data );
1404
+ if (err < 0 )
1405
+ return err ;
1226
1406
1407
+ if (initialization_required ) {
1227
1408
/* PLL configuration is required */
1228
1409
err = si5341_initialize_pll (data );
1229
1410
if (err < 0 )
1230
1411
return err ;
1231
1412
}
1232
1413
1233
1414
/* Register the PLL */
1234
- data -> pxtal_name = __clk_get_name (data -> pxtal );
1235
- init .parent_names = & data -> pxtal_name ;
1236
- init .num_parents = 1 ; /* For now, only XTAL input supported */
1415
+ init .parent_names = data -> input_clk_name ;
1416
+ init .num_parents = SI5341_NUM_INPUTS ;
1237
1417
init .ops = & si5341_clk_ops ;
1238
1418
init .flags = 0 ;
1239
1419
data -> hw .init = & init ;
0 commit comments