diff --git a/cvorg/ad9516/ad9516.c b/cvorg/ad9516/ad9516.c
index c62eccbdc42bb3d37d4260a79de22bf20b078ee5..b2cd8719a01370b1933e9cf34106039315ed4e06 100644
--- a/cvorg/ad9516/ad9516.c
+++ b/cvorg/ad9516/ad9516.c
@@ -1,4 +1,5 @@
 #include <math.h>
+#include <stdio.h>
 
 #include <ad9516.h>
 
@@ -13,6 +14,9 @@ static int ad9516_get_dividers(int freq, struct ad9516_pll *pll)
 	double mindiff = 1e10;
 	int dvco, d1, d2;
 	int i, j, k;
+	double f_vco;
+
+	f_vco = ((double)pll->input_freq/pll->r)*((double)pll->p * pll->b + pll->a);
 
 	/*
 	 * Note: this loop is sub-optimal, since sometimes combinations
@@ -22,7 +26,7 @@ static int ad9516_get_dividers(int freq, struct ad9516_pll *pll)
 	for (i = 2; i <= 6; i++) {
 		for (j = 1; j <= 32; j++) {
 			for (k = j; k <= 32; k++) {
-				diff = (double)AD9516_VCO_FREQ / i / j / k - freq;
+				diff = f_vco / i / j / k - freq;
 				if (fabs(diff) <= (double)AD9516_MAXDIFF)
 					goto found;
 				if (fabs(diff) < fabs(mindiff)) {
@@ -50,15 +54,19 @@ found:
  * Here we consider the dividers fixed, and play with N, R to calculate
  * a satisfactory f_vco, given a certain required output frequency @freq
  */
-static void ad9516_calc_pll_params(int freq, struct ad9516_pll *pll)
+static void __ad9516_calc_pll_params(int freq, struct ad9516_pll *pll, unsigned int ext_clk_freq, int ext_clk)
 {
 	double n, nr;
+	double clk = AD9516_OSCILLATOR_FREQ;
 	/*
 	 * What's the required N / R ?
 	 * N / R = Dividers * freq / fref, where Dividers = dvco * d1 * d1
 	 * and fref = AD9516_OSCILLATOR_FREQ
 	 */
-	nr = (double)pll->dvco * pll->d1 * pll->d2 * freq / AD9516_OSCILLATOR_FREQ;
+	if (ext_clk)
+		clk = ext_clk_freq;
+
+	nr = (double)pll->dvco * pll->d1 * pll->d2 * freq / clk;
 
 	n = nr * pll->r;
 	/*
@@ -66,36 +74,126 @@ static void ad9516_calc_pll_params(int freq, struct ad9516_pll *pll)
 	 */
 	pll->b = ((int)n) / pll->p;
 	pll->a = ((int)n) % pll->p;
+
 }
 
-static int ad9516_check_pll(struct ad9516_pll *pll)
+
+static void ad9516_calc_pll_params(int freq, struct ad9516_pll *pll)
+{
+    __ad9516_calc_pll_params(freq, pll, 0, 0);
+}
+
+static void ad9516_calc_pll_params_ext_clk(int freq, struct ad9516_pll *pll, unsigned int ext_clk_freq)
+{
+    pll->input_freq = ext_clk_freq;
+    __ad9516_calc_pll_params(freq, pll, ext_clk_freq, 1);
+}
+
+static int ad9516_check_pll(struct ad9516_pll *pll, unsigned int ext_clk_freq, int ext_clk)
 {
 	int err = 0;
-	double fvco = (double)AD9516_OSCILLATOR_FREQ *
-		(pll->p * pll->b + pll->a) / pll->r;
+	double clk = AD9516_OSCILLATOR_FREQ;
+	double fvco; 	
 
-	if (pll->a > pll->b)
+	if (ext_clk)
+		clk = ext_clk_freq;
+	
+	fvco = clk * (pll->p * pll->b + pll->a) / pll->r;
+
+	if (pll->a > pll->b) {
 		err = -1;
+	}
 
-	if (pll->a > 63)
+	if (pll->a > 63) {
 		err = -1;
+	}
 
-	if (pll->p != 16 && pll->p != 32)
+	/* valid values are powers of two in 2..32 range) */
+	if (pll->p < 2 || pll->p > 32 || (pll->p & (pll->p -1))) {
 		err = -1;
+	}
 
-	if (pll->b <= 0 || pll->b > 8191)
+	if (pll->b <= 0 || pll->b > 8191) {
 		err = -1;
+	}
 
-	if (pll->r <= 0 || pll->r > 16383)
+	if (pll->r <= 0 || pll->r > 16383) {
 		err = -1;
+	}
 
-	if (fvco < 2.55e9 || fvco > 2.95e9)
+	if (fvco < 2.55e9 || fvco > 2.95e9) {
 		err = -1;
+	}
 
 	return err;
 }
 
-int ad9516_fill_pll_conf(unsigned int freq, struct ad9516_pll *pll)
+int ad9516_get_fvco(unsigned int freq, struct ad9516_pll * pll, unsigned int ext_clk_freq)
+{
+	long int f_vco = 0;
+	int a = 0;
+	int b = 1;
+	int p[5] = {32, 16, 8, 4, 2};
+	int r;
+	int i;
+	double alpha, beta;
+
+	/*
+	 * Using r = 100 the maximum is 7.5e9 Hz that is beyond the maximum unsigned int value.
+	 * Just in case, the comparation is maintained.
+	 */
+	if (ext_clk_freq < 1e6 || ext_clk_freq > 7.5e9)
+		return -1;
+	
+	alpha = AD9516_VCO_FREQ_MIN / ext_clk_freq;
+	beta = AD9516_VCO_FREQ_MAX / ext_clk_freq;
+	
+	// To be sure for getting valid values, the constant is 2.0 instead of 1.0
+	//r = ceil(2.0/(beta - alpha));
+	//if (r <= 0)
+	//	return -1;
+
+	/*
+	 * Use of this constant value (r = 100) to allow the PLL to lock with the external clock.
+	 * The frequency used by the client is 10 MHz. This constant allows to give
+	 * proper values for the rest of parameters.
+	 */
+	r = 100;
+
+	f_vco = ceil(r*alpha);
+
+	if (f_vco < r*alpha || f_vco > r*beta)
+		return -1;
+	
+	// Search the values of p, a, b.
+	for (i = 0; i < 5; i++) {
+		b = f_vco / p[i];
+		a = f_vco % p[i];
+
+		if (b <= 0 || b >= 8192)
+			continue;
+		if (a == 0 || (b > a && b > 3))
+			goto found;
+
+	}
+
+	// Not found proper parameters, give error
+	return -1;
+
+found :
+	pll->a = a;
+	pll->b = b;
+	pll->p = p[i]; 
+	pll->r = r;
+	pll->dvco = 1;
+	pll->d1 = 1;
+	pll->d2 = 1;
+	pll->external = 0;
+
+	return 0;
+} 
+
+int __ad9516_fill_pll_conf(unsigned int freq, struct ad9516_pll *pll, unsigned int ext_clk_freq, int ext_clk)
 {
 	if (!freq) {
 		pll->a = 0;
@@ -110,20 +208,31 @@ int ad9516_fill_pll_conf(unsigned int freq, struct ad9516_pll *pll)
 	}
 
 	/* initial sanity check */
-	if (freq < AD9516_MINFREQ)
+	if (freq < AD9516_MINFREQ){
 		return -1;
+	}
 
 	/*
 	 * Algorithm for adjusting the PLL
-	 * 1. set f_vco = 2.8 GHz
-	 *	N = (p * b) + a -> N = 70000
-	 *	f_vco = f_ref * N / R = 40e6 * 70000 = 2.8e9 Hz
 	 */
-	pll->a = 0;
-	pll->b = 4375;
-	pll->p = 16;
-	pll->r = 1000;
-	pll->external = 0;
+
+	if (!ext_clk) {
+		/*
+	 	 * 1. set f_vco = 2.8 GHz
+	 	 *	N = (p * b) + a -> N = 70000
+	 	 *	f_vco = f_ref * N / R = 40e6 * 70000 = 2.8e9 Hz
+	 	 */
+		pll->a = 0;
+		pll->b = 4375;
+		pll->p = 16;
+		pll->r = 1000;
+		pll->external = 0;
+	} else {
+		// Search for proper parameter values.
+		if (ad9516_get_fvco(freq, pll, ext_clk_freq)) {
+			return -1;
+		}
+	}
 
 	/*
 	 * 2. check if playing with the dividers we can achieve the required
@@ -135,10 +244,29 @@ int ad9516_fill_pll_conf(unsigned int freq, struct ad9516_pll *pll)
 		 * 2.1 Playing with the dividers is not enough: tune the VCO
 		 *     by adjusting the relation N/R.
 		 */
-		ad9516_calc_pll_params(freq, pll);
+		if (ext_clk)
+			ad9516_calc_pll_params_ext_clk(freq, pll, ext_clk_freq);
+		else
+			ad9516_calc_pll_params(freq, pll);
 	}
 
 	/* 3. Check the calculated PLL configuration is feasible */
-	return ad9516_check_pll(pll);
+	return ad9516_check_pll(pll, ext_clk_freq, ext_clk);
+		
 }
 
+int ad9516_fill_pll_conf(unsigned int freq, struct ad9516_pll *pll)
+{
+	pll->ext_clk_pll = 0;
+	pll->external = 0;
+	pll->input_freq = AD9516_OSCILLATOR_FREQ;
+	return __ad9516_fill_pll_conf(freq, pll, 0, 0);
+}
+
+int ad9516_fill_pll_conf_ext_clk(unsigned int freq, struct ad9516_pll *pll, unsigned int ext_clk_freq)
+{
+	pll->ext_clk_pll = 1;
+	pll->external = 0; 	/* As we use the internal PLL this should be zero */
+	pll->input_freq = ext_clk_freq;
+	return __ad9516_fill_pll_conf(freq, pll, ext_clk_freq, 1);
+}
diff --git a/cvorg/ad9516/libad9516.h b/cvorg/ad9516/libad9516.h
index ff5a58655ad0709038b3078a7b4ea929ef78de8c..8d20d2d954ef1735dc2c380917e851d6c18e24a2 100644
--- a/cvorg/ad9516/libad9516.h
+++ b/cvorg/ad9516/libad9516.h
@@ -4,5 +4,5 @@
 #include <ad9516.h>
 
 extern int ad9516_fill_pll_conf(unsigned int freq, struct ad9516_pll *pll);
-
+extern int ad9516_fill_pll_conf_ext_clk(unsigned int freq, struct ad9516_pll *pll, unsigned int ext_clk_freq);
 #endif /* _AD9516_LIB_H_ */
diff --git a/cvorg/driver/clkgen.c b/cvorg/driver/clkgen.c
index 7ef5e01ff16ed5bb8c1ba756e0e4285413341bbf..257ccbf83af3caf6ed5455fa15381af3948d8dfd 100644
--- a/cvorg/driver/clkgen.c
+++ b/cvorg/driver/clkgen.c
@@ -48,8 +48,11 @@ static uint32_t clkgen_rval(struct cvorg *cvorg, unsigned int addr)
 {
 	uint32_t val;
 	int i;
+	int data;
 
-	cvorg_writew(cvorg, CVORG_CLKCTL, CVORG_AD9516_OP_READ | (addr << 8));
+	data = cvorg_readw(cvorg, CVORG_CLKCTL) & 0xFF000000;
+
+	cvorg_writew(cvorg, CVORG_CLKCTL, data | CVORG_AD9516_OP_READ | (addr << 8));
 
 	/* try a few times, although normally 5us should be enough */
 	for (i = 0; i < 3; i++) {
@@ -203,7 +206,7 @@ static int calib_vco_sleep(struct cvorg *cvorg, int r, int freqref)
 	tswait(NULL, SEM_SIGIGNORE, interval + 1);
 
 	/* check for completion */
-	return clkgen_rd(cvorg, AD9516_PLLREADBACK) & 0x40 ? 0 : -1;
+	return clkgen_rd(cvorg, AD9516_PLLREADBACK) & 0x40 ? 0 : -1;  
 }
 
 static int clkgen_read_dvco(struct cvorg *cvorg)
@@ -314,8 +317,6 @@ void get_pll_conf(struct cvorg *cvorg, struct ad9516_pll *pll)
  */
 static void check_pll_dividers(struct ad9516_pll *pll)
 {
-	if (pll->r == 1)
-		pll->r = 0;
 	if (pll->dvco == 1)
 		pll->dvco = 0;
 
@@ -366,7 +367,29 @@ static void clkgen_write_r(struct cvorg *cvorg, int r)
 
 static void clkgen_write_p(struct cvorg *cvorg, int p)
 {
-	int prescaler = p == 16 ? 0x5 : 0x6; /* see the module's docs */
+	int prescaler;
+
+	switch(p) {
+	case 2:
+		prescaler = 0x2;
+		break;
+	case 4: 
+		prescaler = 0x3;
+		break;
+
+	case 8: 
+		prescaler = 0x4;
+		break;
+	case 16: 
+		prescaler = 0x5;
+		break;
+
+	case 32: 
+		prescaler = 0x6;
+		break;
+	default:
+		prescaler = 0x6;
+	}
 
 	/* reset P */
 	clkgen_and(cvorg, AD9516_PLL1, ~0x07);
@@ -464,6 +487,7 @@ int clkgen_apply_pll_conf(struct cvorg *cvorg)
 {
 	int ret = 0;
 	struct ad9516_pll *pll = &cvorg->pll;
+	unsigned int data;
 
 	check_pll_dividers(pll);
 
@@ -489,7 +513,21 @@ int clkgen_apply_pll_conf(struct cvorg *cvorg)
 	clkgen_wr(cvorg, AD9516_PLL3,		0x01);
 	clkgen_wr(cvorg, AD9516_UPDATE_ALL,	0x01);
 
-	if (calib_vco_sleep(cvorg, pll->r, AD9516_OSCILLATOR_FREQ)) {
+	/* Use the external clock as input for the pll
+	 * instead of the internal oscillator.
+	 */
+	
+	if (pll->ext_clk_pll) {
+		data = cvorg_readw(cvorg, CVORG_CLKCTL);
+		cvorg_writew(cvorg, CVORG_CLKCTL, data | (1 << 31));
+	} else {
+
+		data = cvorg_readw(cvorg, CVORG_CLKCTL);
+		cvorg_writew(cvorg, CVORG_CLKCTL, data & 0x7FFFFFFF);
+	}
+
+
+	if (calib_vco_sleep(cvorg, pll->r, pll->input_freq)) {
 		SK_DEBUG("VCO calibration failed [PLL: A=%d B=%d P=%d "
 			"R=%d d1=%d d2=%d dvco=%d]", pll->a, pll->b,
 			pll->p, pll->r, pll->d1, pll->d2, pll->dvco);
@@ -506,12 +544,16 @@ int clkgen_check_pll(struct ad9516_pll *pll)
 
 	if (pll->a > pll->b)
 		err = 1;
+
 	if (pll->a > 63)
 		err = 1;
-	if (pll->p != 16 && pll->p != 32)
+
+	if (pll->p != 4 && pll->p != 8 && pll->p != 16 && pll->p != 16 && pll->p != 32)
 		err = 1;
+
 	if (pll->b <= 0 || pll->b > 8191)
 		err = 1;
+
 	if (pll->r <= 0 || pll->r > 16383)
 		err = 1;
 
diff --git a/cvorg/driver/cvorg-skel.c b/cvorg/driver/cvorg-skel.c
index 1830f2433f24eb9cdf6b4f340b613a44adb48ded..81dd6ca778e6376ae879bf9c6371275ff9a8f08e 100644
--- a/cvorg/driver/cvorg-skel.c
+++ b/cvorg/driver/cvorg-skel.c
@@ -351,6 +351,8 @@ static void cvorg_pll_cfg_init(struct ad9516_pll *pll)
 	pll->d1		= 14;
 	pll->d2		= 1;
 	pll->external	= 0;
+	pll->input_freq = AD9516_OSCILLATOR_FREQ;
+	pll->ext_clk_pll = 0;
 }
 
 #define CVORG_FREQ_DIV	10000
@@ -367,14 +369,18 @@ static int cvorg_poll_sampfreq(struct cvorg *cvorg)
 	unsigned int n = pll->p * pll->b + pll->a;
 	int32_t sampfreq;
 	int32_t freq;
+	unsigned int input_freq = AD9516_OSCILLATOR_FREQ;
 	int i;
 
 	/* When external, we cannot possibly know the desired frequency */
 	if (pll->external)
 		return 0;
 
+	if (pll->ext_clk_pll)
+		input_freq = pll->input_freq;
+
 	/* Note: some dividers may be bypassed (ie set to zero) */
-	freq = AD9516_OSCILLATOR_FREQ / CVORG_FREQ_DIV * n;
+	freq = input_freq / CVORG_FREQ_DIV * n;
 	if (pll->r)
 		freq /= pll->r;
 	if (pll->dvco)
diff --git a/cvorg/include/ad9516.h b/cvorg/include/ad9516.h
index 7205679e085ae06cff23a5050243135dcf8dcff5..cdfc27336ac568e1b0c5dc00971ef22e07a56ca8 100644
--- a/cvorg/include/ad9516.h
+++ b/cvorg/include/ad9516.h
@@ -1,9 +1,11 @@
 #ifndef _AD9516_H_
 #define _AD9516_H_
 
-#define AD9516_VCO_FREQ		2800000000UL
+#define AD9516_VCO_FREQ		2.8e9L
+#define AD9516_VCO_FREQ_MIN	2.55e9L
+#define AD9516_VCO_FREQ_MAX	2.95e9L
 #define AD9516_MAXDIFF		0
-#define AD9516_OSCILLATOR_FREQ	40000000UL
+#define AD9516_OSCILLATOR_FREQ	40e6L
 
 #define AD9516_MINFREQ		416000
 
@@ -17,6 +19,7 @@
  * @d1 - [1,32]
  * @d2 - [1,32]
  * @external - set to 0 to use the internal PLL; 1 to use EXTCLK
+ * @ext_clk_pll - set to 0 to use to use the internal oscillator in the PLL; 1 to use EXTCLK in the PLL.
  */
 struct ad9516_pll {
 	int a;
@@ -27,6 +30,8 @@ struct ad9516_pll {
 	int d1;
 	int d2;
 	int external;
+	int ext_clk_pll;
+	int input_freq;
 };
 
 #endif /* _AD9516_H_ */
diff --git a/cvorg/include/libcvorg.h b/cvorg/include/libcvorg.h
index a1266021e2152901f17ae640994805ef4db13f42..a385fc4f23db96289283d7e539729d7ce7575a09 100644
--- a/cvorg/include/libcvorg.h
+++ b/cvorg/include/libcvorg.h
@@ -33,6 +33,7 @@ int cvorg_unlock(cvorg_t *device);
 
 int cvorg_set_sampfreq(cvorg_t *device, unsigned int freq);
 int cvorg_get_sampfreq(cvorg_t *device, unsigned int *freq);
+int cvorg_set_sampfreq_ext_clk(cvorg_t *device, unsigned int freq, unsigned int ext_clk_freq);
 
 int cvorg_channel_set_outoff(cvorg_t *device, enum cvorg_outoff outoff);
 int cvorg_channel_get_outoff(cvorg_t *device, enum cvorg_outoff *outoff);
diff --git a/cvorg/lib/cvorg.c b/cvorg/lib/cvorg.c
index 9ba080471c7d292128200e654f2279135daae6bb..11f0d779b9ad19b9c590dbb5a41e4bde4d79029e 100644
--- a/cvorg/lib/cvorg.c
+++ b/cvorg/lib/cvorg.c
@@ -195,7 +195,7 @@ int cvorg_unlock(cvorg_t *device)
  * @return 0 on success, -1 on failure
  *
  * This frequency is generated by tuning an internal oscillator. An external
- * clock can be used as well by setting freq to 0.
+ * clock (without using the PLL) can be used as well by setting freq to 0.
  *
  * This function puts the calling process to sleep until the configured
  * frequency is available at the output of the module. Note that this
@@ -231,6 +231,53 @@ int cvorg_set_sampfreq(cvorg_t *device, unsigned int freq)
 	return 0;
 }
 
+/**
+ * @brief Set the sampling frequency of the device using external clock and the internal PLL.
+ * @param device	- CVORG device handle
+ * @param freq		- Desired frequency, in Hz
+ * @param ext_clk_freq	- Frequency of the external clk, in Hz
+ *
+ * @return 0 on success, -1 on failure
+ *
+ * This frequency is generated by tuning an external clock using the PLL.
+ *
+ * The frequency of the external clock should be between 1 MHz and 7.5 GHz.
+ *
+ * This function puts the calling process to sleep until the configured
+ * frequency is available at the output of the module. Note that this
+ * sleeping wait may last for a few hundreds of milliseconds.
+ *
+ * Changing the sampling frequency of a device with any of its channels
+ * in 'busy' state might fail.
+ */
+int cvorg_set_sampfreq_ext_clk(cvorg_t *device, unsigned int freq, unsigned int ext_clk_freq)
+{
+	struct ad9516_pll pll;
+	int ret;
+
+	LIBCVORG_DEBUG(4, "fd %d freq %d\n", device->fd, freq);
+	if (freq > CVORG_MAX_FREQ) {
+		LIBCVORG_DEBUG(2, "Invalid frequency (%d Hz). Max: %d Hz\n",
+			freq, CVORG_MAX_FREQ);
+		__cvorg_errno = LIBCVORG_EINVAL_FREQ;
+		return -1;
+	}
+
+	if (ad9516_fill_pll_conf_ext_clk(freq, &pll, ext_clk_freq)) {
+		__cvorg_internal_error(LIBCVORG_EINVAL_FREQ);
+		return -1;
+	}
+
+	ret = ioctl(device->fd, CVORG_IOCSPLL, &pll);
+
+	if (ret < 0) {
+		__cvorg_libc_error(__func__);
+		return -1;
+	}
+	return 0;
+}
+
+
 /**
  * @brief Get the current sampling frequency of the device
  * @param device	- CVORG device handle
@@ -628,7 +675,7 @@ int cvorg_dac_set_conf(cvorg_t *device, struct cvorg_dac conf)
 	if (status & CVORG_CHANSTAT_BUSY ||
 		status & CVORG_CHANSTAT_SRAM_BUSY) {
 		fprintf(stderr, "current channel is busy. Cannot set DAC configuration.\n");
-		return -1; /* XXX SIG: this return value or another? */
+		return -1;
 	}
 
 	/* Setup the configuration */
diff --git a/cvorg/test/cvorgtest.c b/cvorg/test/cvorgtest.c
index 5d6baa72cd22f84bebe07eb5f43009c6e471c8ec..df98d845c719f179f49623afbb8249e07e7151f2 100644
--- a/cvorg/test/cvorgtest.c
+++ b/cvorg/test/cvorgtest.c
@@ -708,10 +708,11 @@ static void print_pll(struct ad9516_pll *pll)
 {
 	unsigned long n = pll->p * pll->b + pll->a;
 	double fvco;
+	double sampfreq;
 
-	fvco = (double)AD9516_OSCILLATOR_FREQ * n / pll->r;
+	fvco = (double)pll->input_freq * n / pll->r;
 
-	printf("debug: fref=%g, n=%lu, r=%d\n", (double)AD9516_OSCILLATOR_FREQ,
+	printf("debug: fref=%g, n=%lu, r=%d\n", (double)pll->input_freq,
 		n, pll->r);
 
 	printf("PLL params: [P=%d, B=%d, A=%d, R = %d]\n"
@@ -722,19 +723,25 @@ static void print_pll(struct ad9516_pll *pll)
 		"\tf_ref = %g Hz\n"
 		"\tN = %lu\n"
 		"\tf_vco = %g Hz\n",
-		(double)AD9516_OSCILLATOR_FREQ, n, fvco);
+		(double)pll->input_freq, n, fvco);
 
-	if (pll->external) {
+	if (pll->external) 
 		printf("f_out: external\n");
-	} else {
-		double sampfreq = fvco / pll->dvco / pll->d1 / pll->d2;
 
-		printf("f_out: ");
-		if (sampfreq < 1000000)
-			printf("%g KHz", sampfreq / 1e3);
-		else
-			printf("%g MHz", sampfreq / 1e6);
+
+	printf("f_out: ");
+	sampfreq = fvco / pll->dvco / pll->d1 / pll->d2; 
+
+	if (sampfreq < 1000000)
+		printf("%g KHz", sampfreq / 1e3);
+	else
+		printf("%g MHz", sampfreq / 1e6);
 		printf("\n");
+
+	if (pll->ext_clk_pll) {
+		printf("f_input: external\n");
+	} else {
+		printf("f_input: internal oscillator\n");
 	}
 
 }
@@ -776,14 +783,19 @@ out:
 int h_sampfreq(struct cmd_desc *cmdd, struct atom *atoms)
 {
 	struct ad9516_pll pll;
+	unsigned int ext_clk = 0;
+	unsigned int freq;
 
 	if (atoms == (struct atom *)VERBOSE_HELP) {
 		printf("%s - get/set the sampling frequency\n"
 			"%s - print the current sampling frequency\n"
-			"%s n:\n"
+			"%s n [m]:\n"
 			"\tif n == 0, the sampling frequency is EXTCLK\n"
 			"\tif n != 0, set the sampling frequency to "
-			"(approx.) n Hz (using the internal PLL)\n",
+			"(approx.) n Hz (using the internal PLL)\n"
+			"\tif m == 0 or not present, the input of internal PLL is the internal oscillator (40 MHz)\n"
+			"\tif m != 0, set the frequency of the EXTCLK"
+			"(approx.) m Hz (using the internal PLL)\n",
 			cmdd->name, cmdd->name, cmdd->name);
 		goto out;
 	}
@@ -807,10 +819,33 @@ int h_sampfreq(struct cmd_desc *cmdd, struct atom *atoms)
 		printf("Out of range sampfreq. Max: %d\n", CVORG_MAX_FREQ);
 		return -TST_ERR_WRONG_ARG;
 	}
+	
+	freq = atoms->val;
 
-	if (ad9516_fill_pll_conf(atoms->val, &pll)) {
-		printf("Invalid argument\n");
-		return -TST_ERR_WRONG_ARG;
+	if ((++atoms)->type == Terminator) {
+		ext_clk = 0;
+	} else {
+		if (atoms->type != Numeric) {
+			printf("Invalid argument\n");
+			return -TST_ERR_WRONG_ARG;
+		}
+		if(atoms->val == 0)
+			ext_clk = 0;
+		else
+			ext_clk = 1;
+	}
+
+	if (ext_clk) {
+		if (ad9516_fill_pll_conf_ext_clk(freq, &pll, atoms->val)) {
+			printf("Invalid argument\n");
+			return -TST_ERR_WRONG_ARG;
+		}
+
+	} else {
+		if (ad9516_fill_pll_conf(freq, &pll)) {
+			printf("Invalid argument\n");
+			return -TST_ERR_WRONG_ARG;
+		}
 	}
 
 	if (ioctl(_DNFD, CVORG_IOCSPLL, &pll) < 0) {