Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
meta-elphel393
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
meta-elphel393
Commits
e8f2c31a
Commit
e8f2c31a
authored
Dec 09, 2013
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
si5338.c - debugging, comparing to the map by the manufacturers software
parent
530f9049
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
267 additions
and
45 deletions
+267
-45
vsc3304.patch
recipes-kernel/linux/linux-xlnx/vsc3304.patch
+267
-45
No files found.
recipes-kernel/linux/linux-xlnx/vsc3304.patch
View file @
e8f2c31a
Index: git/drivers/misc/Kconfig
===================================================================
--- git.orig/drivers/misc/Kconfig 2013-12-0
7 11:59:45.450394753
-0700
+++ git/drivers/misc/Kconfig 2013-12-0
7 11:59:48.558394785
-0700
--- git.orig/drivers/misc/Kconfig 2013-12-0
8 13:24:02.319343372
-0700
+++ git/drivers/misc/Kconfig 2013-12-0
8 13:24:46.000000000
-0700
@@ -549,6 +549,19 @@
their requirements.
...
...
@@ -24,8 +24,8 @@ Index: git/drivers/misc/Kconfig
source "drivers/misc/eeprom/Kconfig"
Index: git/drivers/misc/Makefile
===================================================================
--- git.orig/drivers/misc/Makefile 2013-12-0
7 11:59:45.450394753
-0700
+++ git/drivers/misc/Makefile 2013-12-0
7 11:59:48.558394785
-0700
--- git.orig/drivers/misc/Makefile 2013-12-0
8 13:24:02.319343372
-0700
+++ git/drivers/misc/Makefile 2013-12-0
8 13:24:46.000000000
-0700
@@ -55,3 +55,5 @@
obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
obj-$(CONFIG_SRAM) += sram.o
...
...
@@ -35,7 +35,7 @@ Index: git/drivers/misc/Makefile
Index: git/drivers/misc/vsc330x.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ git/drivers/misc/vsc330x.c 2013-12-0
7 11:59:48.558394785
-0700
+++ git/drivers/misc/vsc330x.c 2013-12-0
8 13:24:46.000000000
-0700
@@ -0,0 +1,872 @@
+/*!***************************************************************************
+ *! FILE NAME : vsc330x.c
...
...
@@ -912,8 +912,8 @@ Index: git/drivers/misc/vsc330x.c
Index: git/drivers/misc/si5338.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ git/drivers/misc/si5338.c 2013-12-0
8 01:27:57.338897726
-0700
@@ -0,0 +1,3
542
@@
+++ git/drivers/misc/si5338.c 2013-12-0
9 00:58:03.587775288
-0700
@@ -0,0 +1,3
764
@@
+/*!***************************************************************************
+ *! FILE NAME : si5338.c
+ *! DESCRIPTION: control of the Silicon Laboratories SI5338 clock generator
...
...
@@ -968,6 +968,8 @@ Index: git/drivers/misc/si5338.c
+#define MSINT_MIN 8 /* not considering 4,6 */
+#define MSINT_MAX 567
+
+#define INIT_TIMEOUT 1000 /* reads of the I2C status register (1 cycle ~ 0.1 ms) */
+
+#define AWE_IN_MUX 0x1d18
+#define AWE_IN_MUX1 0x1c1c
+#define AWE_FB_MUX 0x1e18
...
...
@@ -1014,13 +1016,10 @@ Index: git/drivers/misc/si5338.c
+#define AWE_DRV2_TRIM 0x297c
+#define AWE_DRV3_TRIM 0x2a1f
+
+#define AWE_FCAL_OVRD_A 0x2bff
+#define AWE_FCAL_OVRD_B 0x2cff
+#define AWE_FCAL_OVRD_C 0x2d03
+
+#define AWE_FCAL_OVRD_07_00 0x2dff
+#define AWE_FCAL_OVRD_15_08 0x2eff
+#define AWE_FCAL_OVRD_17_15 0x2f03
+#define AWE_REG47_72 0x2ffc
+#define AWE_PFD_EXTFB 0x3080
+#define AWE_PLL_KPHI 0x307f
+#define AWE_FCAL_OVRD_EN 0x3180
...
...
@@ -1119,6 +1118,13 @@ Index: git/drivers/misc/si5338.c
+#define AWE_OUT2_DIS_STATE 0x76c0
+#define AWE_OUT3_DIS_STATE 0x7ac0
+
+#define AWE_STATUS 0xdaff
+#define AWE_STATUS_PLL_LOL 0xda10
+#define AWE_STATUS_PLL_LOS_FDBK 0xda08
+#define AWE_STATUS_PLL_LOS_CLKIN 0xda04
+#define AWE_STATUS_PLL_SYS_CAL 0xda01
+
+#define AWE_MS_RESET 0xe204
+
+#define AWE_OUT0_DIS 0xe601
+#define AWE_OUT1_DIS 0xe602
...
...
@@ -1126,6 +1132,26 @@ Index: git/drivers/misc/si5338.c
+#define AWE_OUT3_DIS 0xe608
+#define AWE_OUT_ALL_DIS 0xe610
+
+#define AWE_FCAL_07_00 0xebff
+#define AWE_FCAL_15_08 0xecff
+#define AWE_FCAL_17_16 0xed03
+
+
+#define AWE_DIS_LOS 0xf180
+#define AWE_REG241 0xf1ff
+
+#define AWE_SOFT_RESET 0xf602
+
+
+#define AWE_MS0_SSUPP3_07_00 0x121ff /* set them to 0 - default==1 */
+#define AWE_MS0_SSUPP3_14_08 0x1227f
+#define AWE_MS1_SSUPP3_07_00 0x131ff
+#define AWE_MS1_SSUPP3_14_08 0x1327f
+#define AWE_MS2_SSUPP3_07_00 0x141ff
+#define AWE_MS2_SSUPP3_14_08 0x1427f
+#define AWE_MS3_SSUPP3_07_00 0x151ff
+#define AWE_MS3_SSUPP3_14_08 0x1527f
+
+
+
+#define AWE_MISC_47 0x2ffc /* write 0x5 */
...
...
@@ -1240,18 +1266,24 @@ Index: git/drivers/misc/si5338.c
+
+ {NULL, 0x0,0x0,0x0,0x0},
+};
+static const int volatile_registers[]={
218,
-1};
+static const int volatile_registers[]={
AWE_STATUS, AWE_SOFT_RESET, AWE_FCAL_07_00, AWE_FCAL_15_08, AWE_FCAL_17_16,
-1};
+static const char *out_names[]={"output0","output1","output2","output3","outputs", NULL};
+static const char *in_freq_names[]={"in_frequency12", "in_frequency3", "in_frequency4", "in_frequency56", "in_frequency12xo", NULL};
+static const char *pll_setup_names[]={"pll_freq_fract", "pll_freq_int", "pll_by_out_fract", "pll_by_out_int", NULL};
+static const char *out_freq_setup_names[]={
+ "out0_freq_fract", "out1_freq_fract", "out2_freq_fract", "out3_freq_fract",
+ "out0_freq_int", "out1_freq_int", "out2_freq_int", "out3_freq_int", NULL};
+static u32 awe_msx_ssup3[4][3]=
+ {{AWE_MS0_SSUPP3_07_00,AWE_MS0_SSUPP3_14_08,0},
+ {AWE_MS1_SSUPP3_07_00,AWE_MS1_SSUPP3_14_08,0},
+ {AWE_MS2_SSUPP3_07_00,AWE_MS2_SSUPP3_14_08,0},
+ {AWE_MS3_SSUPP3_07_00,AWE_MS3_SSUPP3_14_08,0}};
+
+static void si5338_init_of(struct i2c_client *client);
+
+static int get_chn_from_name(const char * name);
+
+static ssize_t invalidate_cache_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
+static ssize_t raw_address_show (struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t raw_address_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
+static ssize_t raw_data_show (struct device *dev, struct device_attribute *attr, char *buf);
...
...
@@ -1302,6 +1334,8 @@ Index: git/drivers/misc/si5338.c
+static ssize_t ms_powerdown_show (struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t ms_powerdown_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t pre_init_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
+static ssize_t post_init_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
+static ssize_t pll_freq_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t pll_freq_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
+static ssize_t pll_ms_freq_show(struct device *dev, struct device_attribute *attr, char *buf);
...
...
@@ -1383,7 +1417,9 @@ Index: git/drivers/misc/si5338.c
+static int set_out_frequency_and_route (struct i2c_client *client, u64 *out_freq, int chn, int int_div);
+static s64 get_output_src_frequency(struct i2c_client *client, u64 *out_freq, int chn);
+
+
+static int pre_init(struct i2c_client *client);
+static int post_init(struct i2c_client *client, int timeout); /*1 in timeout ~ 0.1ms - i2c read register */
+static int get_status(struct i2c_client *client);
+static int set_pll_paremeters(struct i2c_client *client);
+static int set_misc_registers(struct i2c_client *client);
+static int get_ms_powerdown(struct i2c_client *client, int chn);
...
...
@@ -1425,24 +1461,28 @@ Index: git/drivers/misc/si5338.c
+static int write_adwe(struct i2c_client *client, u32 adwe);
+static int write_reg(struct i2c_client *client, u16 reg, u8 val, u8 mask);
+static int read_reg(struct i2c_client *client, u16 reg);
+static void invalidate_cache(struct i2c_client *client);
+
+
+/* raw access to i2c registers, need to set address (9 bits) first, then r/w data */
+static DEVICE_ATTR(address, SYSFS_PERMISSIONS, raw_address_show, raw_address_store);
+static DEVICE_ATTR(data, SYSFS_PERMISSIONS, raw_data_show, raw_data_store);
+static DEVICE_ATTR(hex_address, SYSFS_PERMISSIONS, raw_hex_address_show, raw_hex_address_store);
+static DEVICE_ATTR(hex_data, SYSFS_PERMISSIONS, raw_hex_data_show, raw_hex_data_store);
+static DEVICE_ATTR(hex_all, SYSFS_PERMISSIONS & SYSFS_READONLY, raw_hex_all_show, NULL);
+static DEVICE_ATTR(hex_adwe, SYSFS_PERMISSIONS, raw_hex_adwe_show, raw_hex_adwe_store);
+
+static DEVICE_ATTR(invalidate_cache, SYSFS_PERMISSIONS & SYSFS_WRITEONLY, NULL, invalidate_cache_store);
+static DEVICE_ATTR(address, SYSFS_PERMISSIONS, raw_address_show, raw_address_store);
+static DEVICE_ATTR(data, SYSFS_PERMISSIONS, raw_data_show, raw_data_store);
+static DEVICE_ATTR(hex_address, SYSFS_PERMISSIONS, raw_hex_address_show,raw_hex_address_store);
+static DEVICE_ATTR(hex_data, SYSFS_PERMISSIONS, raw_hex_data_show, raw_hex_data_store);
+static DEVICE_ATTR(hex_all, SYSFS_PERMISSIONS & SYSFS_READONLY, raw_hex_all_show, NULL);
+static DEVICE_ATTR(hex_adwe, SYSFS_PERMISSIONS, raw_hex_adwe_show, raw_hex_adwe_store);
+
+static struct attribute *raw_dev_attrs[] = {
+ &dev_attr_address.attr,
+ &dev_attr_data.attr,
+ &dev_attr_hex_address.attr,
+ &dev_attr_hex_data.attr,
+ &dev_attr_hex_all.attr,
+ &dev_attr_hex_adwe.attr,
+ NULL
+ &dev_attr_invalidate_cache.attr,
+ &dev_attr_address.attr,
+ &dev_attr_data.attr,
+ &dev_attr_hex_address.attr,
+ &dev_attr_hex_data.attr,
+ &dev_attr_hex_all.attr,
+ &dev_attr_hex_adwe.attr,
+ NULL
+};
+
+static const struct attribute_group dev_attr_raw_group = {
...
...
@@ -1534,10 +1574,15 @@ Index: git/drivers/misc/si5338.c
+ .attrs = multisynth_attrs,
+ .name = "multiSynth",
+};
+static DEVICE_ATTR(pll_freq_fract, SYSFS_PERMISSIONS, pll_freq_show, pll_freq_store);
+static DEVICE_ATTR(pll_freq_int, SYSFS_PERMISSIONS, pll_freq_show, pll_freq_store);
+static DEVICE_ATTR(pll_by_out_fract,SYSFS_PERMISSIONS, pll_freq_show, pll_freq_store);
+static DEVICE_ATTR(pll_by_out_int, SYSFS_PERMISSIONS, pll_freq_show, pll_freq_store);
+
+
+
+static DEVICE_ATTR(pre_init, SYSFS_PERMISSIONS & SYSFS_WRITEONLY, NULL, pre_init_store);
+static DEVICE_ATTR(post_init, SYSFS_PERMISSIONS & SYSFS_WRITEONLY, NULL, post_init_store);
+static DEVICE_ATTR(pll_freq_fract, SYSFS_PERMISSIONS, pll_freq_show, pll_freq_store);
+static DEVICE_ATTR(pll_freq_int, SYSFS_PERMISSIONS, pll_freq_show, pll_freq_store);
+static DEVICE_ATTR(pll_by_out_fract,SYSFS_PERMISSIONS, pll_freq_show, pll_freq_store);
+static DEVICE_ATTR(pll_by_out_int, SYSFS_PERMISSIONS, pll_freq_show, pll_freq_store);
+
+/* has to have/not have '_fract' in the name */
+static DEVICE_ATTR(pll_ms0_freq_fract,SYSFS_PERMISSIONS, pll_ms_freq_show, pll_ms_freq_store);
...
...
@@ -1551,6 +1596,8 @@ Index: git/drivers/misc/si5338.c
+
+
+static struct attribute *pll_dev_attrs[] = {
+ &dev_attr_pre_init.attr,
+ &dev_attr_post_init.attr,
+ &dev_attr_pll_ref_frequency.attr,
+ &dev_attr_pll_freq_fract.attr,
+ &dev_attr_pll_freq_int.attr,
...
...
@@ -1786,6 +1833,7 @@ Index: git/drivers/misc/si5338.c
+ return (cp)?(cp[0]-'0'):-1;
+}
+
+
+static int make_config_out (struct device *dev,
+ ssize_t (*show_output)(struct device *dev, struct device_attribute *attr, char *buf),
+ ssize_t (*store_config)(struct device *dev, struct device_attribute *attr,
...
...
@@ -1894,6 +1942,7 @@ Index: git/drivers/misc/si5338.c
+ len+=rc;
+ return len;
+}
+
+static ssize_t output_route_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int chn, rc;
...
...
@@ -1903,6 +1952,8 @@ Index: git/drivers/misc/si5338.c
+ return count;
+}
+
+//static void invalidate_cache(struct i2c_client *client)
+
+
+static int get_output_description (struct device *dev, char * buf, int chn)
+{
...
...
@@ -1979,7 +2030,12 @@ Index: git/drivers/misc/si5338.c
+ return retval;
+}
+
+
+static ssize_t invalidate_cache_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ invalidate_cache(client);
+ return count;
+}
+
+static ssize_t raw_address_show (struct device *dev, struct device_attribute *attr, char *buf)
+{
...
...
@@ -2080,14 +2136,14 @@ Index: git/drivers/misc/si5338.c
+ */
+static ssize_t raw_hex_adwe_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ const char
digits[]="0123456789
";
+ const char
hex_digits[]="0123456789abcdefABCDEF
";
+ struct i2c_client *client = to_i2c_client(dev);
+ struct si5338_data_t *clientdata= i2c_get_clientdata(client);
+ int adwe,rc=0;
+ int left=count,num_bytes;
+ const char * cp;
+ mutex_lock(&clientdata->lock);
+ while ((left>0) && ((cp=strpbrk(buf,digits))) && cp[0]){
+ while ((left>0) && ((cp=strpbrk(buf,
hex_
digits))) && cp[0]){
+ left -= (cp-buf);
+ buf = cp;
+ dev_dbg(dev,"left=%d", left);
...
...
@@ -2348,6 +2404,10 @@ Index: git/drivers/misc/si5338.c
+ p123[2]=1;
+ }
+ if (((rc=set_ms_p123(client,p123, chn)))<0) return rc;
+ if (chn<4){
+ /* disable spread spectrum - only this register was changed to 0 from default 1 */
+ if (((rc=write_multireg64(client, 0 , awe_msx_ssup3[chn])))<0) return rc;
+ }
+ return count;
+}
+static ssize_t ms_abc_show(struct device *dev, struct device_attribute *attr, char *buf)
...
...
@@ -2380,6 +2440,10 @@ Index: git/drivers/misc/si5338.c
+ }
+ ms_to_p123(ms,p123);
+ if (((rc=set_ms_p123(client,p123, chn)))<0) return rc;
+ if (chn<4){
+ /* disable spread spectrum - only this register was changed to 0 from default 1 */
+ if (((rc=write_multireg64(client, 0 , awe_msx_ssup3[chn])))<0) return rc;
+ }
+ return count;
+}
+
...
...
@@ -2401,6 +2465,24 @@ Index: git/drivers/misc/si5338.c
+ return count;
+}
+
+static ssize_t pre_init_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ int rc;
+ if (((rc=pre_init(client)))<0) return rc;
+ return count;
+}
+
+static ssize_t post_init_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ int rc,timeout=0;
+ sscanf(buf, "%d", &timeout);
+ if (timeout <=0) timeout=INIT_TIMEOUT;
+ if (((rc=post_init(client,timeout)))<0) return rc;
+ return count;
+}
+
+static ssize_t pll_freq_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int rc;
...
...
@@ -3321,11 +3403,13 @@ Index: git/drivers/misc/si5338.c
+ /* setup MSn division */
+ if (((rc=set_pll_ms_by_out(client, out_freq, chn, int_div)))<0) return rc;
+ /* enable power for selected MS */
+ if (((rc=set_ms_powerdown(client,
1
, chn)))<0) return rc;
+ if (((rc=set_ms_powerdown(client,
0
, chn)))<0) return rc;
+ /* route MSn to the output (6 - use 'own' MS) */
+ if (((rc=set_out_source(client, chn, 6)))<0) return rc;
+ /* setup output (R) division - by 1/2/4/8/16/32 */
+ if (((rc=set_out_div_by_frequency(client, out_freq, chn)))<0) return rc;
+ /* enable power for selected output */
+ if (((rc=set_drv_powerdown(client, 0, chn)))<0) return rc;
+ return 0; /* all done */
+}
+
...
...
@@ -3379,6 +3463,93 @@ Index: git/drivers/misc/si5338.c
+}
+
+/* -----------PLL section--------------------------- */
+static u32 awe_fcal[]= {AWE_FCAL_07_00, AWE_FCAL_15_08, AWE_FCAL_17_16, 0};
+static u32 awe_fcal_ovrd[]={AWE_FCAL_OVRD_07_00, AWE_FCAL_OVRD_15_08, AWE_FCAL_OVRD_17_15, 0};
+static int pre_init(struct i2c_client *client)
+{
+ int rc;
+ if (((rc=write_field(client, 1, AWE_OUT_ALL_DIS )))<0) return rc; /* disable all outputs */
+ if (((rc=write_field(client, 1, AWE_DIS_LOS )))<0) return rc; /* pause LOL */
+ return 0;
+}
+static int post_init(struct i2c_client *client, int timeout) /*1 in timeout ~ 0.1ms - i2c read register */
+{
+ int rc,i,in_src, fb_src,ext_fb,check_los=0;
+ s64 fcal;
+ /* validate input clock status */
+ if (((in_src=get_in_pfd_ref_fb(client,0)))<0) return in_src;
+ switch (in_src){
+ case 0:
+ case 2:
+ case 4:
+ check_los |= AWE_STATUS_PLL_LOS_CLKIN; break;
+ case 1:
+ case 3:
+ check_los |= AWE_STATUS_PLL_LOS_FDBK; break;
+ }
+ if (((ext_fb=read_field(client,AWE_PFD_EXTFB)))<0) return ext_fb;
+ if (ext_fb){
+ if (((fb_src=get_in_pfd_ref_fb(client,1)))<0) return fb_src;
+ switch (in_src){
+ case 1:
+ case 3:
+ check_los |= AWE_STATUS_PLL_LOS_CLKIN; break;
+ case 0:
+ case 2:
+ check_los |= AWE_STATUS_PLL_LOS_FDBK; break;
+ }
+ }
+ check_los &= 0xf;
+ for (i=0;i<timeout;i++){
+ if (((rc=get_status(client)))<0) return rc;
+ if ((rc & check_los)==0) break; /* inputs OK */
+ }
+ if (i>=timeout){
+ dev_err(&client->dev, "Timeout waiting for input clocks, status=0x%x, mask=0x%x\n",rc, check_los);
+ return -EPIPE;
+ }
+ dev_dbg(&client->dev, "Validated input clocks, t=%d cycles (timeout= %d cycles), status =0x%x, mask=0x%x\n",
+ i, timeout, rc, check_los);
+
+ if (((rc=write_field(client, 0, AWE_FCAL_OVRD_EN )))<0) return rc; /* Configure PLL for locking, set FCAL_OVRD_EN=0 */
+ write_field(client, 1, AWE_SOFT_RESET ); /* Configure PLL for locking, set SOFT_RESET=1 (ignore i2c error) */
+ for (i=0;i<250;i++) get_status(client); /* wait 25 ms */
+ if (((rc=write_field(client, 0x65, AWE_REG241 )))<0) return rc; /* re-enable LOL, set reg 241=0x65 */
+
+ check_los |= AWE_STATUS_PLL_LOL | AWE_STATUS_PLL_SYS_CAL;
+ check_los &= 0xf;
+ for (i=0;i<timeout;i++){
+ if (((rc=get_status(client)))<0) return rc;
+ if ((rc & check_los)==0) break; /* alarms not set OK */
+ }
+ if (i>=timeout){
+ dev_err(&client->dev, "Timeout waiting for PLL lock, status=0x%x, mask=0x%x\n",rc, check_los);
+ return -EPIPE;
+ }
+ dev_dbg(&client->dev, "Validated PLL locked, t=%d cycles (timeout= %d cycles), status =0x%x, mask=0x%x\n",
+ i, timeout, rc, check_los);
+
+ /* copy FCAL values to active registers */
+ if (((fcal=read_multireg64 (client, awe_fcal)))<0) return (int) fcal;
+ if (((rc= write_multireg64(client, fcal, awe_fcal_ovrd)))<0) return rc;
+ dev_dbg(&client->dev, "Copied FCAL data 0x%llx\n", fcal);
+ if (((rc=write_field(client, 5, AWE_REG47_72 )))<0) return rc; /* set 47[7:2] to 000101b */
+ if (((rc=write_field(client, 1, AWE_FCAL_OVRD_EN )))<0) return rc; /* SET PLL to use FCAL values, set FCAL_OVRD_EN=1 */
+ /* only needed if using down-spread. Won't hurt to do anyway */
+ if (((rc=write_field(client, 1, AWE_MS_RESET )))<0) return rc; /* SET MS RESET=1 */
+ for (i=0;i<10;i++) get_status(client); /* wait 1 ms */
+ if (((rc=write_field(client, 0, AWE_MS_RESET )))<0) return rc; /* SET MS RESET=0 */
+ if (((rc=write_field(client, 0, AWE_OUT_ALL_DIS )))<0) return rc; /* enable all (enabled individually) outputs */
+ write_field(client, 0, AWE_SOFT_RESET ); /* Not documented - what to do with the soft reset bit - clearing */
+ return 0;
+}
+
+static int get_status(struct i2c_client *client)
+{
+ return read_field(client,AWE_STATUS);
+}
+
+
+static int set_pll_paremeters(struct i2c_client *client)
+{
+ int rc;
...
...
@@ -3433,6 +3604,7 @@ Index: git/drivers/misc/si5338.c
+ AWE_VCO_GAIN_RSEL_BWSEL)))<0) return rc;
+ if (((rc=write_field(client, (u8) mscal, AWE_MSCAL )))<0) return rc;
+ if (((rc=write_field(client, (u8) ms_pec, AWE_MS_PEC)))<0) return rc;
+ if (((rc=write_field(client, 3, AWE_PLL_EN)))<0) return rc; /* enable PLL */
+ return 0;
+}
+
...
...
@@ -3470,6 +3642,7 @@ Index: git/drivers/misc/si5338.c
+ {AWE_MSN_P2_05_00, AWE_MSN_P2_13_06, AWE_MSN_P2_21_14, AWE_MSN_P2_29_22, 0},
+ {AWE_MSN_P3_07_00, AWE_MSN_P3_15_08, AWE_MSN_P3_23_16, AWE_MSN_P3_29_24, 0}}};
+
+
+static const u32 awe_ms_powerdown[]={AWE_MS0_PDN, AWE_MS1_PDN, AWE_MS2_PDN, AWE_MS3_PDN};
+static int get_ms_powerdown(struct i2c_client *client, int chn)
+{
...
...
@@ -3572,6 +3745,7 @@ Index: git/drivers/misc/si5338.c
+ */
+static int set_pll_freq(struct i2c_client *client, u64 *vco_freq, int int_div)
+{
+ int rc;
+ s64 pll_in_freq, pll_in_freq_scaled,pll_out_freq_scaled,d;
+ u32 msn_p123[3];
+ u64 msn[]={0,0,1};
...
...
@@ -3771,9 +3945,15 @@ Index: git/drivers/misc/si5338.c
+ ms_scaled=ms[0]*ms[2]+ms[1];
+ out_freq[1]=pll_freq_scaled*ms[2];
+ out_freq[2]=ms_scaled*pll_out_freq[2];
+ out_freq[0]=div64_u64(out_freq[1],out_freq[2]);
+ out_freq[1]-=out_freq[0]*out_freq[2];
+ remove_common_factor(&out_freq[1]);
+ if (out_freq[2]==0){
+ out_freq[0]=0;
+ out_freq[1]=0;
+ out_freq[2]=1;
+ } else {
+ out_freq[0]=div64_u64(out_freq[1],out_freq[2]);
+ out_freq[1]-=out_freq[0]*out_freq[2];
+ remove_common_factor(&out_freq[1]);
+ }
+ dev_dbg(&client->dev, "MS%d output frequency: %llu+%llu/%llu Hz\n",chn,out_freq[0],out_freq[1],out_freq[2]);
+ return 0;
+}
...
...
@@ -3852,6 +4032,8 @@ Index: git/drivers/misc/si5338.c
+ /* set up registers */
+ ms_to_p123(ms,p123);
+ if (((rc=set_ms_p123(client,p123, chn)))<0) return rc;
+/* disable spread spectrum - only this register was changed to 0 from default 1 */
+ if (((rc=write_multireg64(client, 0 , awe_msx_ssup3[chn])))<0) return rc;
+ return 0;
+}
+/* ----------- Input section ----------------- */
...
...
@@ -4229,14 +4411,19 @@ Index: git/drivers/misc/si5338.c
+static int _write_single_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+ struct si5338_data_t *clientdata = i2c_get_clientdata(client);
+ int ireg=reg;
+ dev_dbg(&client->dev,"device write: slave=0x%x, reg=0x%x, val=0x%x\n", (int) (client->addr),reg,val);
+ if (clientdata && (reg==REG5338_PAGE)) {
+// dev_dbg(&client->dev,"changing page: new=0x%x, was=0x%x\n",val & REG5338_PAGE_MASK,clientdata->last_page);
+ clientdata->last_page=val & REG5338_PAGE_MASK;
+ }
+ if (clientdata && (reg<=LAST_REG) ){
+ clientdata->cache[reg].data= val;
+ clientdata->cache[reg].flags |= CACHE_INIT;
+ if (clientdata) {
+ if (reg==REG5338_PAGE) {
+ // dev_dbg(&client->dev,"changing page: new=0x%x, was=0x%x\n",val & REG5338_PAGE_MASK,clientdata->last_page);
+ clientdata->last_page=val & REG5338_PAGE_MASK;
+ } else {
+ ireg |=(clientdata->last_page)<<8;
+ }
+ if (ireg<=LAST_REG){
+ clientdata->cache[ireg].data= val;
+ clientdata->cache[ireg].flags |= CACHE_INIT;
+ }
+ }
+ return i2c_smbus_write_byte_data(client, reg, val);
+}
...
...
@@ -4257,6 +4444,7 @@ Index: git/drivers/misc/si5338.c
+ val=((val ^ rc) & mask)^ rc;
+ if ((val==rc) && !(clientdata->cache[reg].flags & CACHE_VOLAT)) {
+ dev_dbg(&client->dev,"No change and not volatile -> no write\n");
+ return 0;
+ }
+ }
+ return _write_single_reg(client, reg & 0xff, val);
...
...
@@ -4294,6 +4482,8 @@ Index: git/drivers/misc/si5338.c
+{
+ // struct device *dev=&client->dev;
+ const __be32 * config_data;
+ const char * init_type_string;
+ int init_type=0; /* 0 - none, 1 - always, 2 - if not running (TODO) */
+ struct device_node *node = client->dev.of_node;
+ int len,i,n;
+ u16 page_reg;
...
...
@@ -4308,6 +4498,24 @@ Index: git/drivers/misc/si5338.c
+ struct si5338_setup_data setup_data;
+ __be32 * setup_data_be32= (__be32 *) &setup_data;
+ if (node) {
+ init_type_string = of_get_property(client->dev.of_node, "si5338,init", &len);
+ if (init_type_string){
+ if (strcmp(init_type_string,"always")==0) init_type=1;
+ else if (strcmp(init_type_string,"if off")==0) init_type=2;
+ else {
+ dev_err(&client->dev,"Unrecognized si5338 initialization type '%s'. Only 'always' and 'if off' are permitted\n",init_type_string);
+ }
+ }
+ switch (init_type){
+ case 2:
+ dev_err(&client->dev,"Not yet implemented, initializing unconditionally\n");
+ init_type=1;
+ case 1:
+ pre_init(client);
+ break;
+ }
+
+
+ config_data = of_get_property(client->dev.of_node, "si5338,configuration_data", &len);
+ if (config_data){
+ len /= sizeof(*config_data);
...
...
@@ -4387,11 +4595,25 @@ Index: git/drivers/misc/si5338.c
+ }
+ }
+
+
+ } else {
+ dev_info(&client->dev,"Device tree data not found for %s\n",client->name);
+ }
+ if (init_type){
+ if (post_init(client,INIT_TIMEOUT)<0) dev_err(&client->dev,"SI5338 initialization failed\n");
+ else dev_info(&client->dev,"SI5338 initialized\n");
+ }
+
+}
+
+static void invalidate_cache(struct i2c_client *client)
+{
+ int i;
+ struct si5338_data_t *clientdata = i2c_get_clientdata(client);
+ for (i=0;i<=LAST_REG;i++){
+ clientdata->cache[i].flags&= ~CACHE_INIT;
+ }
+}
+
+
+static int si5338_i2c_probe(struct i2c_client *client,
...
...
@@ -4420,7 +4642,7 @@ Index: git/drivers/misc/si5338.c
+ clientdata->cache[i].data=0;
+ }
+ for (i=0;volatile_registers[i]>=0;i++){
+ clientdata->cache[volatile_registers[i]].flags |= CACHE_VOLAT;
+ clientdata->cache[volatile_registers[i]
>>8
].flags |= CACHE_VOLAT;
+ }
+ //volatile_registers[]
+ i2c_set_clientdata(client, clientdata);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment