
#include <stdio.h>
#include "hmc7044.h"
#include "spi.h"

//#define PLL1_EN

#if 0

struct reg_t hmc7044_configuration[] = {

		/* Load configuration from table 74 */
		{0x00A0								, 0xDF},
		{0x00B0								, 0x04},
		{0x00A5								, 0x06},
		{0x00A8								, 0x06},

		/* Global control */
#ifdef PLL1_EN
		{HMC_GLOBAL_EN_CONTROL_REG			, 0x0F},
#else
		{HMC_GLOBAL_EN_CONTROL_REG			, 0x0E},
#endif
		{HMC_GLOBAL_PAIRS_EN_REG			, 0x0D},
#ifdef PLL1_EN
		{HMC_GLOBAL_EN_MODE_REG				, 0x01},
#else
		{HMC_GLOBAL_EN_MODE_REG				, 0x00},
#endif
		{HMC_GLOBAL_DISABLE_SYNC_REG		, 0x01},

		/* GPIO/SDATA */
		{HMC_GPIO_GPI1_CONTROL_REG			, 0x00},
		{HMC_GPIO_GPI2_CONTROL_REG			, 0x00},
		{HMC_GPIO_GPI3_CONTROL_REG			, 0x00},
		{HMC_GPIO_GPI4_CONTROL_REG			, 0x00},
		{HMC_GPIO_GPO1_CONTROL_REG			, 0x83},
		{HMC_GPIO_GPO2_CONTROL_REG			, 0x7F},
		{HMC_GPIO_GPO3_CONTROL_REG			, 0x1F},
		{HMC_GPIO_GPO4_CONTROL_REG			, 0x2B},
		{HMC_GPIO_SDATA_CONTROL_REG			, 0x03},

		/* PLL2 */
		{HMC_PLL2_DOUBLER_CONTROL_REG		, 0x01},
		{HMC_PLL2_R2_DIV_LSB_REG			, 0x01},
		{HMC_PLL2_R2_DIV_MSB_REG			, 0x00},
		{HMC_PLL2_N2_DIV_LSB_REG			, 0x1E},
		{HMC_PLL2_N2_DIV_MSB_REG			, 0x00},

		/* OSCIN 100R */
		{HMC_PLL1_BUFFER_CONTROL_BASE + HMC_PLL1_OSCIN_OFFSET	, 0x07},

#ifdef PLL1_EN
		/* PLL1 */
		/* CLKIN0 LVPECL & 100R */
		{HMC_PLL1_BUFFER_CONTROL_BASE + HMC_PLL1_CLKIN0_OFFSET	, 0x0B},
		/* OSCIN 100R */
		{HMC_PLL1_BUFFER_CONTROL_BASE + HMC_PLL1_OSCIN_OFFSET	, 0x07},
		/* Reset dividers after exiting holdover */
		{HMC_PLL1_HOLDOVER_EXIT_REG			, 0x00},
		/* Bypass prescaler */
//		{HMC_PLL1_LOS_MODE_CONTROL_REG		, 0x02},
		/* CP current 120 uA as in ADISim project */
		{HMC_PLL1_CH_PUMP_CONTROL_REG		, 0x01},
		/* Enable phase detector up and down */
		{HMC_PLL1_PFD_CONTROL_REG			, 0x18},
		/* Don't want prescaler */
		{HMC_PLL1_PRESCALER_BASE + HMC_PLL1_CLKIN0_OFFSET		, 0x01},
		{HMC_PLL1_PRESCALER_BASE + HMC_PLL1_OSCIN_OFFSET		, 0x0A},
		/* R1 divider = 1 */
		{HMC_PLL1_REF_DIV_LSB_REG			, 0x01},
		{HMC_PLL1_REF_DIV_MSB_REG			, 0x00},
		/* N1 feedback divider = 10 */
		{HMC_PLL1_FEEDBACK_DIV_LSB_REG		, 0x0A},
		{HMC_PLL1_FEEDBACK_DIV_MSB_REG		, 0x00},
		{HMC_PLL1_LOCK_DET_CONTROL_REG		, 0x0F},
		/* Automatic swithing off, holdover ADC, CLKIN0 reference */
		{HMC_PLL1_REF_SWITCH_CONTROL_REG	, 0x04},

#endif

		/* SYSREF/SYNC */
		{HMC_SYSREF_PULSE_GEN_REG			, 0x01},
		{HMC_SYSREF_SYNC_CONTROL_REG		, 0x00},
		{HMC_SYSREF_TIMER_LSB_REG			, 0xFF},
		{HMC_SYSREF_TIMER_MSB_REG			, 0x00},

		/* Clock distribution network */
		{HMC_DIST_EXT_VCO_CONTROL_REG		, 0x00},
		{HMC_DIST_ANALOG_DELAY_REG			, 0x00},

		/* Clock distribution */
		/* Channel 0 */
		{HMC_CLK(0,	HMC_CLK_CONTROL_OFF)	, 0x81},
		{HMC_CLK(0,	HMC_CLK_DIV_LSB_OFF)	, 0x01},
		{HMC_CLK(0,	HMC_CLK_DIV_MSB_OFF)	, 0x00},
		{HMC_CLK(0,	HMC_CLK_OUT_SEL_OFF)	, 0x03},
		{HMC_CLK(0,	HMC_CLK_DRIVER_OFF)		, 0x08},
		/* Channel 1 */
		{HMC_CLK(1,	HMC_CLK_CONTROL_OFF)	, 0x81},
		{HMC_CLK(1,	HMC_CLK_DIV_LSB_OFF)	, 0xB8},
		{HMC_CLK(1,	HMC_CLK_DIV_MSB_OFF)	, 0x0B},
		{HMC_CLK(1,	HMC_CLK_OUT_SEL_OFF)	, 0x00},
		{HMC_CLK(1,	HMC_CLK_DRIVER_OFF)		, 0x08},
		/* Channel 2 */
		{HMC_CLK(2,	HMC_CLK_CONTROL_OFF)	, 0x00},
		/* Channel 3 */
		{HMC_CLK(3,	HMC_CLK_CONTROL_OFF)	, 0x00},
		/* Channel 4 */
		{HMC_CLK(4,	HMC_CLK_CONTROL_OFF)	, 0x81},
		{HMC_CLK(4,	HMC_CLK_DIV_LSB_OFF)	, 0x08},
//		{HMC_CLK(4,	HMC_CLK_DIV_LSB_OFF)	, 0x1E},
		{HMC_CLK(4,	HMC_CLK_DIV_MSB_OFF)	, 0x00},
		{HMC_CLK(4,	HMC_CLK_OUT_SEL_OFF)	, 0x00},
		{HMC_CLK(4,	HMC_CLK_DRIVER_OFF)		, 0x10},
		/* Channel 5 */
		{HMC_CLK(5,	HMC_CLK_CONTROL_OFF)	, 0x00},
		/* Channel 6 */
		{HMC_CLK(6,	HMC_CLK_CONTROL_OFF)	, 0x00},
		/* Channel 7 */
		{HMC_CLK(7,	HMC_CLK_CONTROL_OFF)	, 0x81},
		{HMC_CLK(7,	HMC_CLK_DIV_LSB_OFF)	, 0xB8},
		{HMC_CLK(7,	HMC_CLK_DIV_MSB_OFF)	, 0x0B},
		{HMC_CLK(7,	HMC_CLK_OUT_SEL_OFF)	, 0x00},
		{HMC_CLK(7,	HMC_CLK_DRIVER_OFF)		, 0x10},
		/* Channel 8 */
		{HMC_CLK(8,	HMC_CLK_CONTROL_OFF)	, 0x00},
		/* Channel 9 */
		{HMC_CLK(9,	HMC_CLK_CONTROL_OFF)	, 0x00},
		/* Channel 10 */
		{HMC_CLK(10,HMC_CLK_CONTROL_OFF)	, 0x00},
		/* Channel 11 */
		{HMC_CLK(11,HMC_CLK_CONTROL_OFF)	, 0x00},
		/* Channel 12 */
		{HMC_CLK(12,HMC_CLK_CONTROL_OFF)	, 0x00},
		/* Channel 13 */
		{HMC_CLK(13,HMC_CLK_CONTROL_OFF)	, 0x00},
};

#endif



extern struct reg_t hmc7044_configuration[];
extern int hmc7044_configuration_regs_cnt;



int hmc_write_conf(XSpi *spi)
{
	if(spi_write_conf(spi, hmc7044_configuration, hmc7044_configuration_regs_cnt))
		return 1;

	if(spi_compare_conf(spi, hmc7044_configuration, hmc7044_configuration_regs_cnt))
		return 1;

	return 0;
}
//
//int hmc_write_conf(XSpi *spi)
//{
//	if(spi_write_conf(spi, hmc7044_configuration, sizeof(hmc7044_configuration)/sizeof(*hmc7044_configuration)))
//		return 1;
//
//	if(spi_compare_conf(spi, hmc7044_configuration, sizeof(hmc7044_configuration)/sizeof(*hmc7044_configuration)))
//		return 1;
//
//	return 0;
//}

int hmc_get_pll1_status(XSpi *spi)
{
	uint8_t reg_val = 0;

	if(spi_rw_reg(spi, 0x0082, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x0082, reg_val);
	}

	if(spi_rw_reg(spi, 0x0083, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x0083, reg_val);
	}

	if(spi_rw_reg(spi, 0x0084, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x0084, reg_val);
	}

	if(spi_rw_reg(spi, 0x0085, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x0085, reg_val);
	}

	if(spi_rw_reg(spi, 0x0086, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x0086, reg_val);
	}

	if(spi_rw_reg(spi, 0x007C, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x007C, reg_val);
	}

	if(spi_rw_reg(spi, 0x007D, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x007D, reg_val);
	}

	if(spi_rw_reg(spi, 0x007E, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x007E, reg_val);
	}

	return 0;

}


int hmc_get_pll2_status(XSpi *spi)
{
	uint8_t reg_val = 0;

	if(spi_rw_reg(spi, 0x008C, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x008C, reg_val);
	}

	if(spi_rw_reg(spi, 0x008D, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x008D, reg_val);
	}

	if(spi_rw_reg(spi, 0x008E, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x008E, reg_val);
	}

	if(spi_rw_reg(spi, 0x008F, &reg_val, 0)){
		xil_printf("HMC SPI read failed\n\r");
	}else{
		xil_printf("HMC %04x: %02x\n\r", 0x008F, reg_val);
	}

	return 0;

}















