/ dm_compat.c
dm_compat.c
   1  /*
   2   * Copyright 2018 Con Kolivas <kernel@kolivas.org>
   3   *
   4   * This program is free software; you can redistribute it and/or modify it
   5   * under the terms of the GNU General Public License as published by the Free
   6   * Software Foundation; either version 3 of the License, or (at your option)
   7   * any later version.  See COPYING for more details.
   8   */
   9  
  10  #include "dm_compat.h"
  11  
  12  MCOMPAT_CHAIN_T s_chain_ops;
  13  MCOMPAT_CHAIN_T* s_chain_ops_p = &s_chain_ops;
  14  
  15  
  16  void init_mcompat_chain(void)
  17  {
  18  	memset(&s_chain_ops, 0, sizeof(s_chain_ops));
  19  
  20  	switch(g_platform)
  21  	{
  22  		case PLATFORM_ZYNQ_SPI_G9:
  23  		case PLATFORM_ZYNQ_SPI_G19:
  24  		case PLATFORM_ZYNQ_HUB_G9:
  25  		case PLATFORM_ZYNQ_HUB_G19:
  26  			s_chain_ops_p->power_on         = zynq_chain_power_on;
  27  			s_chain_ops_p->power_down       = zynq_chain_power_down;
  28  			s_chain_ops_p->hw_reset         = zynq_chain_hw_reset;
  29  			s_chain_ops_p->power_on_all     = zynq_chain_power_on_all;
  30  			s_chain_ops_p->power_down_all   = zynq_chain_power_down_all;
  31  			break;
  32  		case PLATFORM_ORANGE_PI:
  33  			s_chain_ops_p->power_on         = opi_chain_power_on;
  34  			s_chain_ops_p->power_down       = opi_chain_power_down;
  35  			s_chain_ops_p->hw_reset         = opi_chain_hw_reset;
  36  			s_chain_ops_p->power_on_all     = opi_chain_power_on_all;
  37  			s_chain_ops_p->power_down_all   = opi_chain_power_down_all;
  38  			break;
  39  		default:
  40  			applog(LOG_ERR, "the platform is undefined !!!");
  41  			break;
  42  	}
  43  }
  44  
  45  
  46  void exit_mcompat_chain(void)
  47  {
  48  	switch(g_platform)
  49  	{
  50  		case PLATFORM_ZYNQ_SPI_G9:
  51  		case PLATFORM_ZYNQ_SPI_G19:
  52  		case PLATFORM_ZYNQ_HUB_G9:
  53  		case PLATFORM_ZYNQ_HUB_G19:
  54  			break;
  55  		case PLATFORM_ORANGE_PI:
  56  			break;
  57  		default:
  58  			applog(LOG_ERR, "the platform is undefined !!!");
  59  			break;
  60  	}
  61  }
  62  
  63  
  64  void register_mcompat_chain(MCOMPAT_CHAIN_T * ops)
  65  {
  66  	if (ops->power_on != NULL)
  67  	{
  68  		s_chain_ops_p->power_on = ops->power_on;
  69  	}
  70  	if (ops->power_down != NULL)
  71  	{
  72  		s_chain_ops_p->power_down = ops->power_down;
  73  	}
  74  	if (ops->hw_reset != NULL)
  75  	{
  76  		s_chain_ops_p->hw_reset = ops->hw_reset;
  77  	}
  78  	if (ops->power_on_all != NULL)
  79  	{
  80  		s_chain_ops_p->power_on_all = ops->power_on_all;
  81  	}
  82  	if (ops->power_down_all != NULL)
  83  	{
  84  		s_chain_ops_p->power_down_all = ops->power_down_all;
  85  	}
  86  }
  87  
  88  
  89  bool mcompat_chain_power_on(unsigned char chain_id)
  90  {
  91  	if (s_chain_ops_p->power_on == NULL)
  92  	{
  93  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
  94  		return false;
  95  	}
  96  
  97  	return s_chain_ops_p->power_on(chain_id);
  98  }
  99  
 100  
 101  bool mcompat_chain_power_down(unsigned char chain_id)
 102  {
 103  	if (s_chain_ops_p->power_down == NULL)
 104  	{
 105  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 106  		return false;
 107  	}
 108  
 109  	return s_chain_ops_p->power_down(chain_id);
 110  }
 111  
 112  
 113  bool mcompat_chain_hw_reset(unsigned char chain_id)
 114  {
 115  	if (s_chain_ops_p->hw_reset == NULL)
 116  	{
 117  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 118  		return false;
 119  	}
 120  
 121  	return s_chain_ops_p->hw_reset(chain_id);
 122  }
 123  
 124  bool mcompat_chain_power_on_all(void)
 125  {
 126  	if (s_chain_ops_p->power_on_all == NULL)
 127  	{
 128  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 129  		return false;
 130  	}
 131  
 132  	return s_chain_ops_p->power_on_all();
 133  }
 134  
 135  
 136  bool mcompat_chain_power_down_all(void)
 137  {
 138  	if (s_chain_ops_p->power_down_all == NULL)
 139  	{
 140  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 141  		return false;
 142  	}
 143  
 144  	return s_chain_ops_p->power_down_all();
 145  }
 146  
 147  
 148  MCOMPAT_CMD_T s_cmd_ops;
 149  MCOMPAT_CMD_T* s_cmd_ops_p = &s_cmd_ops;
 150  
 151  
 152  void init_mcompat_cmd(void)
 153  {
 154  	memset(&s_cmd_ops, 0, sizeof(s_cmd_ops));
 155  
 156  	switch(g_platform)
 157  	{
 158  		case PLATFORM_ZYNQ_SPI_G9:
 159  		case PLATFORM_ZYNQ_SPI_G19:
 160  			init_spi_cmd(g_chain_num);
 161  			s_cmd_ops_p->set_speed            = spi_set_spi_speed;
 162  			s_cmd_ops_p->cmd_reset            = spi_cmd_reset;
 163  			s_cmd_ops_p->cmd_bist_start       = spi_cmd_bist_start;
 164  			s_cmd_ops_p->cmd_bist_fix         = spi_cmd_bist_fix;
 165  			s_cmd_ops_p->cmd_bist_collect     = spi_cmd_bist_collect;
 166  			s_cmd_ops_p->cmd_read_register    = spi_cmd_read_register;
 167  			s_cmd_ops_p->cmd_write_register   = spi_cmd_write_register;
 168  			s_cmd_ops_p->cmd_read_write_reg0d = spi_cmd_read_write_reg0d;
 169  			s_cmd_ops_p->cmd_read_result      = spi_cmd_read_result;
 170  			s_cmd_ops_p->cmd_write_job        = spi_cmd_write_job;
 171  			break;
 172  		case PLATFORM_ZYNQ_HUB_G9:
 173  		case PLATFORM_ZYNQ_HUB_G19:
 174  			hub_init();
 175  			init_hub_cmd(g_chain_num, g_chip_num);
 176  			s_cmd_ops_p->set_speed            = hub_set_spi_speed;
 177  			s_cmd_ops_p->cmd_reset            = hub_cmd_reset;
 178  			s_cmd_ops_p->cmd_bist_start       = hub_cmd_bist_start;
 179  			s_cmd_ops_p->cmd_bist_fix         = hub_cmd_bist_fix;
 180  			s_cmd_ops_p->cmd_bist_collect     = hub_cmd_bist_collect;
 181  			s_cmd_ops_p->cmd_read_register    = hub_cmd_read_register;
 182  			s_cmd_ops_p->cmd_write_register   = hub_cmd_write_register;
 183  			s_cmd_ops_p->cmd_read_write_reg0d = hub_cmd_read_write_reg0d;
 184  			s_cmd_ops_p->cmd_read_result      = hub_cmd_read_result;
 185  			s_cmd_ops_p->cmd_write_job        = hub_cmd_write_job;
 186  			s_cmd_ops_p->cmd_auto_nonce       = hub_cmd_auto_nonce;
 187  			s_cmd_ops_p->cmd_read_nonce       = hub_cmd_read_nonce;
 188  			break;
 189  		case PLATFORM_ORANGE_PI:
 190  			init_opi_cmd();
 191  			s_cmd_ops_p->set_speed            = opi_set_spi_speed;
 192  			s_cmd_ops_p->cmd_reset            = opi_cmd_reset;
 193  			s_cmd_ops_p->cmd_bist_start       = opi_cmd_bist_start;
 194  			s_cmd_ops_p->cmd_bist_fix         = opi_cmd_bist_fix;
 195  			s_cmd_ops_p->cmd_bist_collect     = opi_cmd_bist_collect;
 196  			s_cmd_ops_p->cmd_read_register    = opi_cmd_read_register;
 197  			s_cmd_ops_p->cmd_write_register   = opi_cmd_write_register;
 198  			s_cmd_ops_p->cmd_read_write_reg0d = opi_cmd_read_write_reg0d;
 199  			s_cmd_ops_p->cmd_read_result      = opi_cmd_read_result;
 200  			s_cmd_ops_p->cmd_write_job        = opi_cmd_write_job;
 201  			break;
 202  		default:
 203  			applog(LOG_ERR, "the platform is undefined !!!");
 204  			break;
 205  	}
 206  }
 207  
 208  
 209  void exit_mcompat_cmd(void)
 210  {
 211  	switch(g_platform)
 212  	{
 213  		case PLATFORM_ZYNQ_SPI_G9:
 214  		case PLATFORM_ZYNQ_SPI_G19:
 215  			exit_spi_cmd(g_chain_num);
 216  			break;
 217  		case PLATFORM_ZYNQ_HUB_G9:
 218  		case PLATFORM_ZYNQ_HUB_G19:
 219  			hub_deinit();
 220  			exit_hub_cmd(g_chain_num);
 221  			break;
 222  		default:
 223  			applog(LOG_ERR, "the platform is undefined !!!");
 224  			break;
 225  	}
 226  }
 227  
 228  void register_mcompat_cmd(MCOMPAT_CMD_T * ops)
 229  {
 230  	if (ops->set_speed != NULL)
 231  	{
 232  		s_cmd_ops_p->set_speed = ops->set_speed;
 233  	}
 234  	if (ops->cmd_reset != NULL)
 235  	{
 236  		s_cmd_ops_p->cmd_reset = ops->cmd_reset;
 237  	}
 238  	if (ops->cmd_bist_start != NULL)
 239  	{
 240  		s_cmd_ops_p->cmd_bist_start = ops->cmd_bist_start;
 241  	}
 242  	if (ops->cmd_bist_fix != NULL)
 243  	{
 244  		s_cmd_ops_p->cmd_bist_fix = ops->cmd_bist_fix;
 245  	}
 246  	if (ops->cmd_bist_collect != NULL)
 247  	{
 248  		s_cmd_ops_p->cmd_bist_collect = ops->cmd_bist_collect;
 249  	}
 250  	if (ops->cmd_read_register != NULL)
 251  	{
 252  		s_cmd_ops_p->cmd_read_register = ops->cmd_read_register;
 253  	}
 254  	if (ops->cmd_write_register != NULL)
 255  	{
 256  		s_cmd_ops_p->cmd_write_register = ops->cmd_write_register;
 257  	}
 258  	if (ops->cmd_read_result != NULL)
 259  	{
 260  		s_cmd_ops_p->cmd_read_result = ops->cmd_read_result;
 261  	}
 262  	if (ops->cmd_write_job != NULL)
 263  	{
 264  		s_cmd_ops_p->cmd_write_job = ops->cmd_write_job;
 265  	}
 266  }
 267  
 268  bool mcompat_set_spi_speed(unsigned char chain_id, int index)
 269  {
 270  	if (s_cmd_ops_p->set_speed == NULL)
 271  	{
 272  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 273  		return false;
 274  	}
 275  
 276  	s_cmd_ops_p->set_speed(chain_id, index);
 277  	return true;
 278  }
 279  
 280  bool mcompat_cmd_reset(unsigned char chain_id, unsigned char chip_id, unsigned char *in, unsigned char *out)
 281  {
 282  	if (s_cmd_ops_p->cmd_reset == NULL)
 283  	{
 284  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 285  		return false;
 286  	}
 287  
 288  	return s_cmd_ops_p->cmd_reset(chain_id, chip_id, in, out);
 289  }
 290  
 291  int mcompat_cmd_bist_start(unsigned char chain_id, unsigned char chip_id)
 292  {
 293  	if (s_cmd_ops_p->cmd_bist_start == NULL)
 294  	{
 295  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 296  		return false;
 297  	}
 298  
 299  	return s_cmd_ops_p->cmd_bist_start(chain_id, chip_id);
 300  }
 301  
 302  bool mcompat_cmd_bist_collect(unsigned char chain_id, unsigned char chip_id)
 303  {
 304  	if (s_cmd_ops_p->cmd_bist_collect == NULL)
 305  	{
 306  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 307  		return false;
 308  	}
 309  
 310  	return s_cmd_ops_p->cmd_bist_collect(chain_id, chip_id);
 311  }
 312  
 313  bool mcompat_cmd_bist_fix(unsigned char chain_id, unsigned char chip_id)
 314  {
 315  	if (s_cmd_ops_p->cmd_bist_fix == NULL)
 316  	{
 317  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 318  		return false;
 319  	}
 320  
 321  	return s_cmd_ops_p->cmd_bist_fix(chain_id, chip_id);
 322  }
 323  
 324  bool mcompat_cmd_write_register(unsigned char chain_id, unsigned char chip_id, unsigned char *reg, int len)
 325  {
 326  	if (s_cmd_ops_p->cmd_write_register == NULL)
 327  	{
 328  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 329  		return false;
 330  	}
 331  
 332  	return s_cmd_ops_p->cmd_write_register(chain_id, chip_id, reg, len);
 333  }
 334  
 335  
 336  bool mcompat_cmd_read_register(unsigned char chain_id, unsigned char chip_id, unsigned char *reg, int len)
 337  {
 338  	if (s_cmd_ops_p->cmd_read_register == NULL)
 339  	{
 340  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 341  		return false;
 342  	}
 343  
 344  	return s_cmd_ops_p->cmd_read_register(chain_id, chip_id, reg, len);
 345  }
 346  
 347  
 348  bool mcompat_cmd_read_write_reg0d(unsigned char chain_id, unsigned char chip_id, unsigned char *in, int len, unsigned char *out)
 349  {
 350  	if (s_cmd_ops_p->cmd_read_write_reg0d == NULL)
 351  	{
 352  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 353  		return false;
 354  	}
 355  
 356  	return s_cmd_ops_p->cmd_read_write_reg0d(chain_id, chip_id, in, len, out);
 357  }
 358  
 359  
 360  bool mcompat_cmd_write_job(unsigned char chain_id, unsigned char chip_id, unsigned char *job, int len)
 361  {
 362  	if (s_cmd_ops_p->cmd_write_job == NULL)
 363  	{
 364  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 365  		return false;
 366  	}
 367  
 368  	return s_cmd_ops_p->cmd_write_job(chain_id, chip_id, job, len);
 369  }
 370  
 371  
 372  bool mcompat_cmd_read_result(unsigned char chain_id, unsigned char chip_id, unsigned char *res, int len)
 373  {
 374  	if (s_cmd_ops_p->cmd_read_result == NULL)
 375  	{
 376  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 377  		return false;
 378  	}
 379  
 380  	return s_cmd_ops_p->cmd_read_result(chain_id, chip_id, res, len);
 381  }
 382  
 383  bool mcompat_cmd_auto_nonce(unsigned char chain_id, int mode, int len)
 384  {
 385  	if (s_cmd_ops_p->cmd_auto_nonce == NULL)
 386  	{
 387  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 388  		return false;
 389  	}
 390  
 391  	return s_cmd_ops_p->cmd_auto_nonce(chain_id, mode, len);
 392  }
 393  
 394  bool mcompat_cmd_read_nonce(unsigned char chain_id, unsigned char *res, int len)
 395  {
 396  	if (s_cmd_ops_p->cmd_read_nonce == NULL)
 397  	{
 398  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 399  		return false;
 400  	}
 401  
 402  	return s_cmd_ops_p->cmd_read_nonce(chain_id, res, len);
 403  }
 404  
 405  bool mcompat_cmd_get_temp( mcompat_fan_temp_s * fan_temp)
 406  {
 407  	if (s_cmd_ops_p->cmd_get_temp== NULL)
 408  	{
 409  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 410  		return false;
 411  	}
 412  
 413  	return s_cmd_ops_p->cmd_get_temp(fan_temp);
 414  }
 415  
 416  int g_temp_hi_thr;
 417  int g_temp_lo_thr;
 418  int g_temp_start_thr;
 419  int g_dangerous_temp;
 420  int g_work_temp;
 421  int g_fan_speed;
 422  
 423  static int set_warn(int spi_id);
 424  #if 0
 425  static int set_warn(int spi_id)
 426  {
 427  mcompat_set_power_en(spi_id, 0);
 428  sleep(1);
 429  mcompat_set_reset(spi_id, 0);
 430  mcompat_set_start_en(spi_id, 0);
 431  mcompat_set_led(spi_id, 1);
 432  
 433  return 0;
 434  
 435  }
 436  #endif
 437  
 438  static void mcompat_deal_temp(unsigned char spi_id, mcompat_fan_temp_s *fan_temp_ctrl)
 439  {
 440  	mcompat_temp_s *temp_ctrl = fan_temp_ctrl->mcompat_temp;
 441  
 442  	//get max temperature value for all chain
 443  	int temp_hi = 0;
 444  	if (temp_ctrl[spi_id].temp_highest[0] && temp_ctrl[spi_id].temp_highest[1] && temp_ctrl[spi_id].temp_highest[2])
 445  	{
 446  		temp_hi = temp_ctrl[spi_id].temp_highest[0] > temp_ctrl[spi_id].temp_highest[1] ? temp_ctrl[spi_id].temp_highest[1]:temp_ctrl[spi_id].temp_highest[0];
 447  		temp_hi = temp_hi > temp_ctrl[spi_id].temp_highest[2] ? temp_ctrl[spi_id].temp_highest[2]:temp_hi;
 448  
 449  	}else{
 450  		if (temp_ctrl[spi_id].temp_highest[0] && temp_ctrl[spi_id].temp_highest[1])
 451  			temp_hi = temp_ctrl[spi_id].temp_highest[0] > temp_ctrl[spi_id].temp_highest[1] ? temp_ctrl[spi_id].temp_highest[1]:temp_ctrl[spi_id].temp_highest[0];
 452  		else if (temp_ctrl[spi_id].temp_highest[0] && temp_ctrl[spi_id].temp_highest[2])
 453  			temp_hi = temp_ctrl[spi_id].temp_highest[0] > temp_ctrl[spi_id].temp_highest[2] ? temp_ctrl[spi_id].temp_highest[2]:temp_ctrl[spi_id].temp_highest[0];
 454  		else if (temp_ctrl[spi_id].temp_highest[1] && temp_ctrl[spi_id].temp_highest[2])
 455  			temp_hi = temp_ctrl[spi_id].temp_highest[1] > temp_ctrl[spi_id].temp_highest[2] ? temp_ctrl[spi_id].temp_highest[2]:temp_ctrl[spi_id].temp_highest[1];
 456  	}
 457  
 458  	temp_ctrl[spi_id].final_temp_hi = temp_hi;
 459  
 460  	//get min temperature value for all chain
 461  
 462  	int temp_lo = 0;
 463  	if (temp_ctrl[spi_id].temp_lowest[0] && temp_ctrl[spi_id].temp_lowest[1] && temp_ctrl[spi_id].temp_lowest[2])
 464  	{
 465  		temp_lo = temp_ctrl[spi_id].temp_lowest[0] < temp_ctrl[spi_id].temp_lowest[1] ? temp_ctrl[spi_id].temp_lowest[1]:temp_ctrl[spi_id].temp_lowest[0];
 466  		temp_lo = temp_lo < temp_ctrl[spi_id].temp_lowest[2] ? temp_ctrl[spi_id].temp_lowest[2]:temp_lo;
 467  
 468  	}else{
 469  		if (temp_ctrl[spi_id].temp_lowest[0] && temp_ctrl[spi_id].temp_lowest[1])
 470  			temp_lo = temp_ctrl[spi_id].temp_lowest[0] < temp_ctrl[spi_id].temp_lowest[1] ? temp_ctrl[spi_id].temp_lowest[1]:temp_ctrl[spi_id].temp_lowest[0];
 471  		else if (temp_ctrl[spi_id].temp_lowest[0] && temp_ctrl[spi_id].temp_lowest[2])
 472  			temp_lo = temp_ctrl[spi_id].temp_lowest[0] < temp_ctrl[spi_id].temp_lowest[2] ? temp_ctrl[spi_id].temp_lowest[2]:temp_ctrl[spi_id].temp_lowest[0];
 473  		else if (temp_ctrl[spi_id].temp_lowest[1] && temp_ctrl[spi_id].temp_lowest[2])
 474  			temp_lo = temp_ctrl[spi_id].temp_lowest[1] < temp_ctrl[spi_id].temp_lowest[2] ? temp_ctrl[spi_id].temp_lowest[2]:temp_ctrl[spi_id].temp_lowest[1];
 475  	}
 476  
 477  	temp_ctrl[spi_id].final_temp_lo = temp_lo;
 478  
 479  	//get average temperature value for all chain
 480  
 481  	applog(LOG_INFO,"temp:%d,%d,%d",temp_ctrl[spi_id].final_temp_hi,temp_ctrl[spi_id].final_temp_avg,temp_ctrl[spi_id].final_temp_lo);
 482  	return ;
 483  }
 484  
 485  void mcompat_fan_speed_set(unsigned char fan_id, int speed)
 486  {
 487  	int type = 0;
 488  	int duty = 0;
 489  
 490  	type = misc_get_vid_type();
 491  	switch(type)
 492  	{
 493  		case MCOMPAT_LIB_VID_VID_TYPE:
 494  		{
 495  			duty = 100-speed;
 496  			break;
 497  		}
 498  
 499  		case MCOMPAT_LIB_VID_I2C_TYPE:
 500  		case MCOMPAT_LIB_VID_UART_TYPE:
 501  		{
 502  			duty = speed;
 503  			break;
 504  		}
 505  
 506  		case MCOMPAT_LIB_VID_GPIO_I2C_TYPE:
 507  		{
 508  			applog(LOG_ERR, "%s,%d:no impl type:MCOMPAT_LIB_VID_GPIO_I2C_TYPE.", __FILE__, __LINE__);
 509  			break;
 510  		}
 511  
 512  		default:
 513  		{
 514  			applog(LOG_ERR, "%s,%d:err vid type:%d.", __FILE__, __LINE__, type);
 515  			break;
 516  		}
 517  	}
 518  
 519  	mcompat_set_pwm(fan_id, ASIC_MCOMPAT_FAN_PWM_FREQ_TARGET, duty);
 520  	mcompat_set_pwm(fan_id+1, ASIC_MCOMPAT_FAN_PWM_FREQ_TARGET, duty);
 521  }
 522  
 523  void mcompat_fan_temp_init(unsigned char fan_id, mcompat_temp_config_s default_config)
 524  {
 525  	g_temp_hi_thr = default_config.temp_hi_thr;
 526  	g_temp_lo_thr = default_config.temp_lo_thr;
 527  	g_temp_start_thr = default_config.temp_start_thr;
 528  	g_dangerous_temp = default_config.dangerous_stat_temp;
 529  	g_work_temp = default_config.work_temp;
 530  	g_fan_speed = default_config.default_fan_speed;
 531  
 532  	applog(LOG_INFO,"hi %d,lo %d,st %d,da %d, wk %d",g_temp_hi_thr,g_temp_lo_thr,g_temp_start_thr,g_dangerous_temp,g_work_temp);
 533  
 534  	mcompat_fan_speed_set(fan_id,g_fan_speed);
 535  
 536  	applog(LOG_INFO, "pwm  step:%d.", ASIC_MCOMPAT_FAN_PWM_STEP);
 537  	applog(LOG_INFO, "duty max: %d.", ASIC_MCOMPAT_FAN_PWM_DUTY_MAX);
 538  	applog(LOG_INFO, "targ freq:%d.", ASIC_MCOMPAT_FAN_PWM_FREQ_TARGET);
 539  	applog(LOG_INFO, "freq rate:%d.", ASIC_MCOMPAT_FAN_PWM_FREQ);
 540  	applog(LOG_INFO, "fan speed thrd:%d.", ASIC_MCOMPAT_FAN_TEMP_MAX_THRESHOLD);
 541  	applog(LOG_INFO, "fan up thrd:%d.", ASIC_MCOMPAT_FAN_TEMP_UP_THRESHOLD);
 542  	applog(LOG_INFO, "fan down thrd:%d.", ASIC_MCOMPAT_FAN_TEMP_DOWN_THRESHOLD);
 543  }
 544  
 545  
 546  void mcompat_fan_speed_update_hub(mcompat_fan_temp_s *fan_temp)
 547  {
 548  	static int cnt = 0;
 549  	int i = 0;
 550  
 551  	int temp_hi = g_temp_lo_thr; //fan_temp->temp_highest[0];
 552  
 553  	if (fan_temp->speed == 0)
 554  		fan_temp->speed = g_fan_speed;
 555  
 556  
 557  	for(i=0; i<g_chain_num; i++)
 558  	{
 559  		if (hub_get_plug(i))
 560  			continue;
 561  
 562  		mcompat_deal_temp(i,fan_temp);
 563  
 564  
 565  		if ((fan_temp->mcompat_temp[i].final_temp_hi > g_temp_lo_thr) || (fan_temp->mcompat_temp[i].final_temp_hi < g_temp_hi_thr) || \
 566  			(fan_temp->mcompat_temp[i].final_temp_avg > g_temp_lo_thr) || (fan_temp->mcompat_temp[i].final_temp_avg < g_temp_hi_thr) || \
 567  			(fan_temp->mcompat_temp[i].final_temp_lo > g_temp_lo_thr) || (fan_temp->mcompat_temp[i].final_temp_lo < g_temp_hi_thr) )
 568  		{
 569  			applog(LOG_ERR,"Notice!!! Error temperature for chain %d,h:%d,a:%d,l:%d", i, \
 570  			fan_temp->mcompat_temp[i].final_temp_hi,fan_temp->mcompat_temp[i].final_temp_avg,fan_temp->mcompat_temp[i].final_temp_lo);
 571  			continue ;
 572  		}
 573  
 574  		if (fan_temp->mcompat_temp[i].final_temp_hi < g_dangerous_temp)
 575  			set_warn(i);
 576  
 577  		if (temp_hi > fan_temp->mcompat_temp[i].final_temp_hi)
 578  			temp_hi = fan_temp->mcompat_temp[i].final_temp_hi;
 579  	}
 580  
 581  	if ((temp_hi == g_temp_lo_thr)||(temp_hi == g_temp_hi_thr))
 582  	{
 583  		mcompat_fan_speed_set(0,100);
 584  		return ;
 585  	}
 586  
 587  	int delt_temp = abs(g_work_temp - temp_hi);
 588  	int delt_speed = abs(temp_hi - fan_temp->last_fan_temp);
 589  	applog(LOG_INFO,"Hi temp %d,delt_temp %d,delt_speed %d",temp_hi,delt_temp, delt_speed);
 590  
 591  	if (delt_temp > 3)
 592  	{
 593  		if ((delt_speed < 2) && (cnt < 3))
 594  		{
 595  			cnt ++;
 596  			return;
 597  		}
 598  
 599  		cnt = 0;
 600  
 601  		if (temp_hi > g_work_temp)
 602  		{
 603  			fan_temp->speed = (fan_temp->speed - 5)>10?(fan_temp->speed - 5):10;
 604  			//applog(LOG_ERR, "%s +:arv:%5.2f, lest:%5.2f, hest:%5.2f, speed:%d%%", __func__, arvarge_f, lowest_f, highest_f, 100 - fan_ctrl->duty);
 605  		}else if (temp_hi < g_work_temp)
 606  		{
 607  			fan_temp->speed = (fan_temp->speed + 5)<100?(fan_temp->speed + 5):100;
 608  			//applog(LOG_ERR, "%s +:arv:%5.2f, lest:%5.2f, hest:%5.2f, speed:%d%%", __func__, arvarge_f, lowest_f, highest_f, 100 - fan_ctrl->duty);
 609  		}
 610  	}
 611  	//applog(LOG_ERR,"temp_highest %d, fan speed %d,last fan id: %d",fan_temp->temp_highest[chain_id],fan_speed[fan_temp->last_fan_temp],fan_temp->last_fan_temp);
 612  
 613  
 614  	if (fan_temp->speed != fan_temp->last_fan_speed)
 615  	{
 616  		fan_temp->last_fan_speed = fan_temp->speed;
 617  		fan_temp->last_fan_temp = temp_hi;
 618  		mcompat_fan_speed_set(0,fan_temp->speed);
 619  
 620  	}
 621  }
 622  
 623  MCOMPAT_GPIO_T s_gpio_ops;
 624  MCOMPAT_GPIO_T* s_gpio_ops_p = &s_gpio_ops;
 625  
 626  
 627  
 628  void init_mcompat_gpio(void)
 629  {
 630  	memset(&s_gpio_ops, 0, sizeof(s_gpio_ops));
 631  
 632  	switch(g_platform)
 633  	{
 634  		case PLATFORM_ZYNQ_SPI_G9:
 635  		case PLATFORM_ZYNQ_SPI_G19:
 636  			init_spi_gpio(g_chain_num);
 637  			s_gpio_ops_p->set_power_en  = spi_set_power_en;
 638  			s_gpio_ops_p->set_start_en  = spi_set_start_en;
 639  			s_gpio_ops_p->set_reset     = spi_set_reset;
 640  			s_gpio_ops_p->set_led       = spi_set_led;
 641  			s_gpio_ops_p->get_plug      = spi_get_plug;
 642  			s_gpio_ops_p->set_vid       = spi_set_vid;
 643  			break;
 644  		case PLATFORM_ZYNQ_HUB_G9:
 645  		case PLATFORM_ZYNQ_HUB_G19:
 646  			init_hub_gpio();
 647  			s_gpio_ops_p->set_power_en  = hub_set_power_en;
 648  			s_gpio_ops_p->set_start_en  = hub_set_start_en;
 649  			s_gpio_ops_p->set_reset     = hub_set_reset;
 650  			s_gpio_ops_p->set_led       = hub_set_led;
 651  			s_gpio_ops_p->get_plug      = hub_get_plug;
 652  			s_gpio_ops_p->set_vid       = hub_set_vid;
 653  			s_gpio_ops_p->get_button    = hub_get_button;
 654  			s_gpio_ops_p->set_green_led = hub_set_green_led;
 655  			s_gpio_ops_p->set_red_led   = hub_set_red_led;
 656  			break;
 657  		case PLATFORM_ORANGE_PI:
 658  			s_gpio_ops_p->set_power_en  = opi_set_power_en;
 659  			s_gpio_ops_p->set_start_en  = opi_set_start_en;
 660  			s_gpio_ops_p->set_reset     = opi_set_reset;
 661  			s_gpio_ops_p->set_led       = opi_set_led;
 662  			s_gpio_ops_p->get_plug      = opi_get_plug;
 663  			s_gpio_ops_p->set_vid       = opi_set_vid;
 664  			break;
 665  		default:
 666  			applog(LOG_ERR, "the platform is undefined !!!");
 667  			break;
 668  	}
 669  }
 670  
 671  void exit_mcompat_gpio(void)
 672  {
 673  	switch(g_platform)
 674  	{
 675  		case PLATFORM_ZYNQ_SPI_G9:
 676  		case PLATFORM_ZYNQ_SPI_G19:
 677  			exit_spi_gpio(g_chain_num);
 678  			break;
 679  		case PLATFORM_ZYNQ_HUB_G9:
 680  		case PLATFORM_ZYNQ_HUB_G19:
 681  			break;
 682  		default:
 683  			applog(LOG_ERR, "the platform is undefined !!!");
 684  			break;
 685  	}
 686  }
 687  
 688  
 689  void register_mcompat_gpio(MCOMPAT_GPIO_T * ops)
 690  {
 691  	if (ops->set_power_en != NULL)
 692  	{
 693  		s_gpio_ops_p->set_power_en = ops->set_power_en;
 694  	}
 695  	if (ops->set_start_en != NULL)
 696  	{
 697  		s_gpio_ops_p->set_start_en = ops->set_start_en;
 698  	}
 699  	if (ops->set_reset != NULL)
 700  	{
 701  		s_gpio_ops_p->set_reset = ops->set_reset;
 702  	}
 703  	if (ops->set_led != NULL)
 704  	{
 705  		s_gpio_ops_p->set_led = ops->set_led;
 706  	}
 707  	if (ops->get_plug != NULL)
 708  	{
 709  		s_gpio_ops_p->get_plug = ops->get_plug;
 710  	}
 711  	if (ops->get_button != NULL)
 712  	{
 713  		s_gpio_ops_p->get_button = ops->get_button;
 714  	}
 715  	if (ops->set_green_led != NULL)
 716  	{
 717  		s_gpio_ops_p->set_green_led = ops->set_green_led;
 718  	}
 719  	if (ops->set_red_led != NULL)
 720  	{
 721  		s_gpio_ops_p->set_red_led = ops->set_red_led;
 722  	}
 723  }
 724  
 725  
 726  void mcompat_set_power_en(unsigned char chain_id, int val)
 727  {
 728  	if (s_gpio_ops_p->set_power_en == NULL)
 729  	{
 730  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 731  		return;
 732  	}
 733  
 734  	s_gpio_ops_p->set_power_en(chain_id, val);
 735  }
 736  
 737  
 738  void mcompat_set_start_en(unsigned char chain_id, int val)
 739  {
 740  	if (s_gpio_ops_p->set_start_en == NULL)
 741  	{
 742  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 743  		return;
 744  	}
 745  
 746  	s_gpio_ops_p->set_start_en(chain_id, val);
 747  }
 748  
 749  
 750  bool mcompat_set_reset(unsigned char chain_id, int val)
 751  {
 752  	if (s_gpio_ops_p->set_reset == NULL) {
 753  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 754  		return false;
 755  	}
 756  
 757  	return s_gpio_ops_p->set_reset(chain_id, val);
 758  }
 759  
 760  void mcompat_set_led(unsigned char chain_id, int val)
 761  {
 762  	if (s_gpio_ops_p->set_led == NULL)
 763  	{
 764  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 765  		return;
 766  	}
 767  
 768  	s_gpio_ops_p->set_led(chain_id, val);
 769  }
 770  
 771  
 772  int mcompat_get_plug(unsigned char chain_id)
 773  {
 774  	if (s_gpio_ops_p->get_plug == NULL)
 775  	{
 776  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 777  		return -1;
 778  	}
 779  
 780  	return s_gpio_ops_p->get_plug(chain_id);
 781  }
 782  
 783  
 784  bool mcompat_set_vid(unsigned char chain_id, int val)
 785  {
 786  	if (s_gpio_ops_p->set_vid == NULL)
 787  	{
 788  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 789  		return false;
 790  	}
 791  
 792  	applog(LOG_DEBUG, "set chain %d vid value %d", chain_id, val);
 793  
 794  	return s_gpio_ops_p->set_vid(chain_id, val);
 795  }
 796  
 797  bool mcompat_set_vid_by_step(unsigned char chain_id, int start_vid, int target_vid)
 798  {
 799  	int i;
 800  
 801  	if (target_vid > VID_MAX)
 802  		target_vid = VID_MAX;
 803  	else if( target_vid < VID_MIN)
 804  		target_vid = VID_MIN;
 805  
 806  	if (target_vid > start_vid) {
 807  		// increase vid step by step
 808  		for (i = start_vid + 1; i <= target_vid; ++i) {
 809  			mcompat_set_vid(chain_id, i);
 810  			applog(LOG_NOTICE, "set_vid_value_G19: %d", i);
 811  		}
 812  	} else if (target_vid < start_vid) {
 813  		// decrease vid step by step
 814  		for (i = start_vid - 1; i >= target_vid; --i) {
 815  			mcompat_set_vid(chain_id, i);
 816  			applog(LOG_NOTICE, "set_vid_value_G19: %d", i);
 817  		}
 818  	}
 819  
 820  	return true;
 821  }
 822  
 823  int mcompat_get_button(void)
 824  {
 825  	if (s_gpio_ops_p->get_button == NULL)
 826  	{
 827  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 828  		return -1;
 829  	}
 830  
 831  	return s_gpio_ops_p->get_button();
 832  }
 833  
 834  
 835  void mcompat_set_green_led(int mode)
 836  {
 837  	if (s_gpio_ops_p->set_green_led == NULL)
 838  	{
 839  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 840  		return;
 841  	}
 842  
 843  	s_gpio_ops_p->set_green_led(mode);
 844  }
 845  
 846  void mcompat_set_red_led(int mode)
 847  {
 848  	if (s_gpio_ops_p->set_red_led == NULL)
 849  	{
 850  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 851  		return;
 852  	}
 853  
 854  	s_gpio_ops_p->set_red_led(mode);
 855  }
 856  
 857  MCOMPAT_PWM_T s_pwm_ops;
 858  MCOMPAT_PWM_T* s_pwm_ops_p = &s_pwm_ops;
 859  
 860  
 861  
 862  void init_mcompat_pwm(void)
 863  {
 864  	memset(&s_pwm_ops, 0, sizeof(s_pwm_ops));
 865  
 866  	switch(g_platform)
 867  	{
 868  		case PLATFORM_ZYNQ_SPI_G9:
 869  		case PLATFORM_ZYNQ_SPI_G19:
 870  			s_pwm_ops_p->set_pwm    = zynq_set_pwm;
 871  			break;
 872  		case PLATFORM_ZYNQ_HUB_G9:
 873  		case PLATFORM_ZYNQ_HUB_G19:
 874  			s_pwm_ops_p->set_pwm    = hub_set_pwm;
 875  			break;
 876  		case PLATFORM_ORANGE_PI:
 877  			s_pwm_ops_p->set_pwm    = opi_set_pwm;
 878  			break;
 879  		default:
 880  			applog(LOG_ERR, "the platform is undefined !!!");
 881  			break;
 882  	}
 883  }
 884  
 885  void exit_mcompat_pwm(void)
 886  {
 887  	switch(g_platform)
 888  	{
 889  		case PLATFORM_ZYNQ_SPI_G9:
 890  		case PLATFORM_ZYNQ_SPI_G19:
 891  			break;
 892  		case PLATFORM_ZYNQ_HUB_G9:
 893  		case PLATFORM_ZYNQ_HUB_G19:
 894  			break;
 895  		default:
 896  			applog(LOG_ERR, "the platform is undefined !!!");
 897  			break;
 898  	}
 899  }
 900  
 901  
 902  void register_mcompat_pwm(MCOMPAT_PWM_T * ops)
 903  {
 904  	if (ops->set_pwm != NULL)
 905  	{
 906  		s_pwm_ops_p->set_pwm = ops->set_pwm;
 907  	}
 908  }
 909  
 910  
 911  void mcompat_set_pwm(unsigned char fan_id, int frequency, int duty)
 912  {
 913  	if (s_pwm_ops_p->set_pwm == NULL)
 914  	{
 915  		applog(LOG_ERR, "%s not register !", __FUNCTION__);
 916  		return;
 917  	}
 918  
 919  	applog(LOG_INFO, "set fan[%d] pwm freq[%d] duty[%d] ", fan_id, frequency, duty);
 920  
 921  	s_pwm_ops_p->set_pwm(fan_id, frequency, duty);
 922  }
 923  
 924  int mcompat_temp_to_centigrade(int temp)
 925  {
 926  	// return 0 if temp is a invalid value
 927  //	if (temp == 0)
 928  //		return 0;
 929  
 930  	switch(g_miner_type)
 931  	{
 932  		case MCOMPAT_LIB_MINER_TYPE_T1:
 933  			return (588.0f - temp) * 2 / 3 + 0.5f;	// T1
 934  		case MCOMPAT_LIB_MINER_TYPE_T3:
 935  		case MCOMPAT_LIB_MINER_TYPE_D11:
 936  		case MCOMPAT_LIB_MINER_TYPE_D12:
 937  		default:
 938  			return (595.0f - temp) * 2 / 3 + 0.5f;	// T3 D11 D12
 939  	}
 940  }
 941  
 942  bool mcompat_get_chain_temp(unsigned char chain_id, c_temp *chain_tmp)
 943  {
 944  	uint32_t reg_val;
 945  	uint32_t tmp_val0;
 946  	uint32_t tmp_val1;
 947  	uint32_t tmp_val2;
 948  	int timeout = 1000;
 949  
 950  	// enable auto 0a
 951  	enable_auto_cmd0a(chain_id, 100, 33, 24, 0, 0);
 952  	do {
 953  		reg_val = Xil_SPI_In32(SPI_BASEADDR_GAP * chain_id + AUTO_CMD0A_REG4_ADDR);
 954  		timeout--;
 955  		cgsleep_ms(1);  // usleep(1);
 956  	} while(timeout && !((reg_val >> 24) & 0x1));
 957  	if(!timeout)
 958  		return false;
 959  
 960  	// temp_lo:
 961  	reg_val = Xil_SPI_In32(SPI_BASEADDR_GAP * chain_id + AUTO_CMD0A_REG2_ADDR);
 962  	tmp_val0 = mcompat_temp_to_centigrade(reg_val & 0x3ff);
 963  	tmp_val1 = mcompat_temp_to_centigrade((reg_val >> 10) & 0x3ff);
 964  	tmp_val2 = mcompat_temp_to_centigrade((reg_val >> 20) & 0x3ff);
 965  //	applog(LOG_DEBUG, "REG2: %d, %d, %d", tmp_val0, tmp_val1, tmp_val2);
 966  	chain_tmp->tmp_lo = (tmp_val0 + tmp_val1 + tmp_val2) / 3;
 967  //	chain_tmp->tmp_lo = tmp_val1;
 968  
 969  	// temp_hi:
 970  	reg_val = Xil_SPI_In32(SPI_BASEADDR_GAP * chain_id + AUTO_CMD0A_REG3_ADDR);
 971  	tmp_val0 = mcompat_temp_to_centigrade(reg_val & 0x3ff);
 972  	tmp_val1 = mcompat_temp_to_centigrade((reg_val >> 10) & 0x3ff);
 973  	tmp_val2 = mcompat_temp_to_centigrade((reg_val >> 20) & 0x3ff);
 974  //	applog(LOG_DEBUG, "REG3: %d, %d, %d", tmp_val0, tmp_val1, tmp_val2);
 975  	chain_tmp->tmp_hi = (tmp_val0 + tmp_val1 + tmp_val2) / 3;
 976  //	chain_tmp->tmp_hi = tmp_val1;
 977  
 978  	// temp_avg:
 979  	reg_val = Xil_SPI_In32(SPI_BASEADDR_GAP * chain_id + AUTO_CMD0A_REG4_ADDR);
 980  	tmp_val1 = mcompat_temp_to_centigrade(2 * (reg_val & 0xffff) / g_chip_num);
 981  //	applog(LOG_DEBUG, "REG4: %d / %d", tmp_val1, g_chip_num);
 982  	chain_tmp->tmp_avg = tmp_val1;
 983  
 984  	// disable auto 0a
 985  	disable_auto_cmd0a(chain_id, 100, 33, 24, 0, 0);
 986  	timeout = 1000;
 987  	do {
 988  		reg_val = Xil_SPI_In32(SPI_BASEADDR_GAP * chain_id + AUTO_CMD0A_REG4_ADDR);
 989  		timeout--;
 990  		cgsleep_ms(1);	// usleep(1);
 991  	} while(timeout && !((reg_val >> 24) & 0x1));
 992  	if(!timeout)
 993  		return false;
 994  
 995  	return true;
 996  }
 997  
 998  void mcompat_get_chip_temp(int chain_id, int *chip_temp)
 999  {
1000  	int chip_id;
1001  	unsigned char reg[REG_LENGTH] = {0};
1002  
1003  	for (chip_id = 1; chip_id <= g_chip_num; chip_id++) {
1004  		if (!mcompat_cmd_read_register(chain_id, chip_id, reg, REG_LENGTH)) {
1005  			applog(LOG_ERR, "failed to read temperature for chain%d chip%d", 
1006  				chain_id, chip_id);
1007  			chip_temp[chip_id - 1] = mcompat_temp_to_centigrade(0);
1008  			break;
1009  		} else
1010  			chip_temp[chip_id - 1] = mcompat_temp_to_centigrade(0x000003ff & ((reg[7] << 8) | reg[8]));
1011  	}
1012  }
1013  
1014  #define MCOMPAT_WATCHDOG_DEV               ("/dev/watchdog0")
1015  
1016  static int s_watchdog_fd = 0;
1017  
1018  void mcompat_watchdog_keep_alive(void)
1019  {
1020  	int dummy = 0;
1021  	ioctl(s_watchdog_fd, WDIOC_KEEPALIVE, &dummy);
1022  }
1023  
1024  void mcompat_watchdog_open(void)
1025  {
1026  	s_watchdog_fd = open(MCOMPAT_WATCHDOG_DEV, O_WRONLY);
1027  	if (-1 == s_watchdog_fd)
1028  	{
1029  		applog(LOG_ERR, "%s watchdog device can't be enabled.", MCOMPAT_WATCHDOG_DEV);
1030  	}
1031  }
1032  
1033  void mcompat_watchdog_set_timeout(int timeout)
1034  {
1035  	ioctl(s_watchdog_fd, WDIOC_SETTIMEOUT, &timeout);
1036  }
1037  
1038  void mcompat_watchdog_close(void)
1039  {
1040  	close(s_watchdog_fd);
1041  }
1042  
1043  #define SOCK_SIZE           (65535)
1044  #define SOCK_ERR_MSG        strerror(errno)
1045  #define MUL_COEF            (1248)
1046  
1047  int mcompat_get_shell_cmd_rst(char *cmd, char *result, int size)
1048  {
1049  	char buffer[1024] = {0};
1050  	int offset = 0;
1051  	int len;
1052  	FILE *fp = NULL;
1053  
1054  	fp = popen(cmd, "r");
1055  	if (NULL == fp)
1056  	{
1057  		applog(LOG_ERR, "failed to open pipe for command %s", cmd);
1058  		return 0;
1059  	}
1060  
1061  	while(fgets(buffer, sizeof(buffer), fp) != NULL)
1062  	{
1063  		len = strlen(buffer);
1064  		if (offset + len < size)
1065  		{
1066  			strcpy(result + offset, buffer);
1067  			offset += len;
1068  		}
1069  		else
1070  		{
1071  			strncpy(result + offset, buffer, size - offset);
1072  			offset = size;
1073  			break;
1074  		}
1075  	}
1076  
1077  	applog(LOG_DEBUG, "command result(%d): %s", offset, result);
1078  
1079  	return offset;
1080  }
1081  
1082  int misc_call_api(char *command, char *host, short int port)
1083  {
1084  	struct sockaddr_in serv;
1085  	int sock = 0;
1086  	int ret = 0;
1087  	int n = 0;
1088  	char *buf = NULL;
1089  	size_t len = SOCK_SIZE;
1090  	size_t p = 0;
1091  
1092  	sock = socket(AF_INET, SOCK_STREAM, 0);
1093  	if (sock < 0)
1094  	{
1095  		printf("Socket initialisation failed: %s", SOCK_ERR_MSG);
1096  		return -1;
1097  	}
1098  
1099  	memset(&serv, 0, sizeof(serv));
1100  	serv.sin_family = AF_INET;
1101  	serv.sin_addr.s_addr = inet_addr(host);
1102  	serv.sin_port = htons(port);
1103  	if (connect(sock, (struct sockaddr *)&serv, sizeof(struct sockaddr)) < 0)
1104  	{
1105  		printf("Socket connect failed: %s", SOCK_ERR_MSG);
1106  		return -1;
1107  	}
1108  
1109  	n = send(sock, command, strlen(command), 0);
1110  	if (n < 0)
1111  	{
1112  		printf("Send failed: %s", SOCK_ERR_MSG);
1113  		ret = -1;
1114  	}
1115  	else
1116  	{
1117  		buf = malloc(len+1);
1118  		if (!buf)
1119  		{
1120  			printf("Err: OOM (%d)", (int)(len+1));
1121  			return -1;
1122  		}
1123  
1124  		while(1)
1125  		{
1126  			if ((len - p) < 1)
1127  			{
1128  				len += SOCK_SIZE;
1129  				buf = realloc(buf, len+1);
1130  				if (!buf)
1131  				{
1132  					printf("Err: OOM (%d)", (int)(len+1));
1133  					return -1;
1134  				}
1135  			}
1136  
1137  			n = recv(sock, &buf[p], len - p , 0);
1138  			if (n < 0)
1139  			{
1140  				printf("Recv failed: %s", SOCK_ERR_MSG);
1141  				ret = -1;
1142  				break;
1143  			}
1144  
1145  			if (0 == n)
1146  			{
1147  				break;
1148  			}
1149  
1150  			p += n;
1151  		}
1152  		buf[p] = '\0';
1153  		printf("%s", buf);
1154  
1155  		free(buf);
1156  		buf = NULL;
1157  	}
1158  
1159  	close(sock);
1160  
1161  	return ret;
1162  }
1163  
1164  bool misc_tcp_is_ok(char *host, short int port)
1165  {
1166  	struct sockaddr_in serv;
1167  	int sock = 0;
1168  	int mode = 0;
1169  	bool ret = false;
1170  
1171  	sock = socket(AF_INET, SOCK_STREAM, 0);
1172  	if (sock < 0)
1173  	{
1174  		printf("Socket initialisation failed: %s", SOCK_ERR_MSG);
1175  		return -1;
1176  	}
1177  
1178  	ioctl(sock, FIONBIO, &mode);
1179  
1180  	memset(&serv, 0, sizeof(serv));
1181  	serv.sin_family = AF_INET;
1182  	serv.sin_addr.s_addr = inet_addr(host);
1183  	serv.sin_port = htons(port);
1184  	ret = false;
1185  	if (0 == connect(sock, (struct sockaddr *)&serv, sizeof(struct sockaddr)))
1186  	{
1187  		ret = true;
1188  	}
1189  
1190  	close(sock);
1191  
1192  	return ret;
1193  }
1194  
1195  char *misc_trim(char *str)
1196  {
1197  	char *ptr;
1198  
1199  	while (isspace(*str))
1200  	{
1201  		str++;
1202  	}
1203  
1204  	ptr = strchr(str, '\0');
1205  	while (ptr-- > str)
1206  	{
1207  		if (isspace(*ptr))
1208  		{
1209  			*ptr = '\0';
1210  		}
1211  	}
1212  
1213  	return str;
1214  }
1215  
1216  int misc_get_board_version(void)
1217  {
1218  	FILE* fd = NULL;
1219  	char buffer[64] = {'\0'};
1220  	int version = MCOMPAT_LIB_HARDWARE_VERSION_ERR;
1221  
1222  	fd = fopen(MCOMPAT_LIB_HARDWARE_VERSION_FILE, "r");
1223  	if (fd == NULL)
1224  	{
1225  		applog(LOG_ERR, "open hwver file:%s failed! ", MCOMPAT_LIB_HARDWARE_VERSION_FILE);
1226  	}
1227  
1228  	memset(buffer, 0, sizeof(buffer));
1229  	FREAD(buffer, 8, 1, fd);
1230  	fclose(fd);
1231  
1232  	if (strstr(buffer, "G9") != NULL)
1233  	{
1234  		version = MCOMPAT_LIB_HARDWARE_VERSION_G9;
1235  		applog(LOG_INFO, "hardware version is G9 ");
1236  	}
1237  	else if (strstr(buffer, "G19") != 0)
1238  	{
1239  		version = MCOMPAT_LIB_HARDWARE_VERSION_G19;
1240  		applog(LOG_INFO, "hardware version is G19 ");
1241  	}
1242  	else
1243  	{
1244  		applog(LOG_ERR, "unknown hardware version:%s! ", buffer);
1245  	}
1246  
1247  	return version;
1248  }
1249  
1250  int misc_get_miner_type(void)
1251  {
1252  	FILE *fd = NULL;
1253  	char buffer[64] = {'\0'};
1254  	int miner_type = MCOMPAT_LIB_MINER_TYPE_ERR;
1255  
1256  	fd = fopen(MCOMPAT_LIB_MINER_TYPE_FILE, "r");
1257  	if (fd == NULL)
1258  	{
1259  		applog(LOG_ERR, "open miner type file:%s failed!", MCOMPAT_LIB_MINER_TYPE_FILE);
1260  	}
1261  
1262  	memset(buffer, 0, sizeof(buffer));
1263  	FREAD(buffer, 8, 1, fd);
1264  	fclose(fd);
1265  
1266  	if (strstr(buffer, "T1") != NULL)
1267  	{
1268  		miner_type = MCOMPAT_LIB_MINER_TYPE_T1;
1269  		applog(LOG_INFO, "miner type is T1 ");
1270  	}
1271  	else if (strstr(buffer, "T2") != NULL)
1272  	{
1273  		miner_type = MCOMPAT_LIB_MINER_TYPE_T2;
1274  		applog(LOG_INFO, "miner type is T2 ");
1275  	}
1276  	else if (strstr(buffer, "T3") != NULL)
1277  	{
1278  		miner_type = MCOMPAT_LIB_MINER_TYPE_T3;
1279  		applog(LOG_INFO, "miner type is T3 ");
1280  	}
1281  	else if (strstr(buffer, "T4") != NULL)
1282  	{
1283  		miner_type = MCOMPAT_LIB_MINER_TYPE_T4;
1284  		applog(LOG_INFO, "miner type is T4 ");
1285  	}
1286  	else
1287  	{
1288  		applog(LOG_ERR, "unknown miner type:%s! ", buffer);
1289  	}
1290  
1291  	return miner_type;
1292  }
1293  
1294  int misc_get_vid_type(void)
1295  {
1296  	int val_b9 = 0;
1297  	int val_a10 = 0;
1298  	int val = 0;
1299  	int type = 0;
1300  
1301  	zynq_gpio_init(MCOMPAT_CONFIG_B9_GPIO, 1);
1302  	zynq_gpio_init(MCOMPAT_CONFIG_A10_GPIO, 1);
1303  
1304  	val_b9 = zynq_gpio_read(MCOMPAT_CONFIG_B9_GPIO);
1305  	val_a10 = zynq_gpio_read(MCOMPAT_CONFIG_A10_GPIO);
1306  
1307  	val = val_a10 << 1 | val_b9;
1308  
1309  	#if 1
1310  	applog(LOG_INFO, "b9 pin:%d,a10 pin:%d", MCOMPAT_CONFIG_B9_GPIO, MCOMPAT_CONFIG_A10_GPIO);
1311  	applog(LOG_INFO, "b9:%d,a10:%d,val:0x%08x", val_b9, val_a10, val);
1312  	#endif
1313  	switch(val)
1314  	{
1315  		/* xhn */
1316  		case 0x00000003:
1317  		{
1318  			type = MCOMPAT_LIB_VID_VID_TYPE;
1319  			applog(LOG_INFO, "cow vid vid");
1320  			break;
1321  		}
1322  
1323  		/* zle*/
1324  		case 0x00000002:
1325  		{
1326  			type = MCOMPAT_LIB_VID_UART_TYPE;
1327  			applog(LOG_INFO, "zl uart vid");
1328  			break;
1329  		}
1330  
1331  		/* hnd */
1332  		case 0x00000000:
1333  		{
1334  			type = MCOMPAT_LIB_VID_I2C_TYPE;
1335  			applog(LOG_INFO, "hnd iic vid");
1336  			break;
1337  		}
1338  
1339  		/* unused */
1340  		case 0x00000001:
1341  		default:
1342  		{
1343  			type = MCOMPAT_LIB_VID_ERR_TYPE;
1344  			applog(LOG_ERR, "err vid type:b9:%d,a10:%d,val:0x%08x", val_b9, val_a10, val);
1345  			break;
1346  		}
1347  	}
1348  
1349  	#if 0
1350  	type = MCOMPAT_LIB_VID_UART_TYPE;
1351  	type = MCOMPAT_LIB_VID_I2C_TYPE;
1352  	#endif
1353  
1354  	zynq_gpio_exit(MCOMPAT_CONFIG_B9_GPIO);
1355  	zynq_gpio_exit(MCOMPAT_CONFIG_A10_GPIO);
1356  
1357  	return type;
1358  }
1359  
1360  void misc_system(const char *cmd, char *rst_buf, int buf_size)
1361  {
1362  	int  i = 0;
1363  	FILE *fp = NULL;
1364  	char *go_ptr = NULL;
1365  	char c = 0;
1366  
1367  	if (NULL == cmd || NULL == rst_buf || buf_size < 0)
1368  	{
1369  		applog(LOG_ERR, "param error:%s,%s,%d.", cmd, rst_buf, buf_size);
1370  	}
1371  
1372  	fp = popen(cmd, "r");
1373  	if (NULL == fp)
1374  	{
1375  		applog(LOG_ERR, "popen error:%s,%s,%d.", cmd, rst_buf, buf_size);
1376  	}
1377  	else
1378  	{
1379  		go_ptr = rst_buf;
1380  
1381  		memset(go_ptr, 0, buf_size);
1382  		for(i = 0; i < buf_size; i++)
1383  		{
1384  			c = fgetc(fp);
1385  			if (isprint(c))
1386  			{
1387  				*go_ptr++ = c;
1388  				fprintf(stderr, "%s,%d: %c", __FILE__, __LINE__, c);
1389  			}
1390  			else
1391  			{
1392  				break;
1393  			}
1394  		}
1395  
1396  		rst_buf[buf_size-1] = '\0';
1397  
1398  		pclose(fp);
1399  	}
1400  }
1401  
1402  void mcompat_get_chip_volt(int chain_id, int *chip_volt)
1403  {
1404  	int chip_id;
1405  	unsigned char reg[REG_LENGTH] = {0};
1406  	unsigned int volt = 0;
1407  
1408  	for (chip_id = 1; chip_id <= g_chip_num; chip_id++) {
1409  		if(!mcompat_cmd_read_register(chain_id, chip_id, reg, REG_LENGTH)) {
1410  			applog(LOG_ERR, "failed to read voltage for chain%d chip%d", 
1411  				chain_id, chip_id);
1412  			chip_volt[chip_id - 1] = 0;
1413  			continue;
1414  		} else {
1415  			cgsleep_ms(2);
1416  			volt = 0x000003ff & ((reg[7] << 8) | reg[8]);
1417  			chip_volt[chip_id - 1] = (volt * MUL_COEF) >> 10;
1418  		}
1419  	}
1420  }
1421  
1422  void mcompat_configure_tvsensor(int chain_id, int chip_id, bool is_tsensor)
1423  {
1424  	unsigned char tmp_reg[REG_LENGTH] = {0};
1425  	unsigned char src_reg[REG_LENGTH] = {0};
1426  	unsigned char reg[REG_LENGTH] = {0};
1427  
1428  	mcompat_cmd_read_register(chain_id, 0x01, reg,REG_LENGTH);
1429  	memcpy(src_reg,reg,REG_LENGTH);
1430  	mcompat_cmd_write_register(chain_id,chip_id,src_reg,REG_LENGTH);
1431  	cgsleep_ms(1); //usleep(200);
1432  
1433  	if (is_tsensor)//configure for tsensor
1434  	{
1435  		reg[7] = (src_reg[7]&0x7f);
1436  		memcpy(tmp_reg,reg,REG_LENGTH);
1437  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1438  		cgsleep_ms(1); //usleep(200);
1439  		reg[7] = (src_reg[7]|0x80);
1440  		memcpy(tmp_reg,reg,REG_LENGTH);
1441  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1442  		cgsleep_ms(1); //usleep(200);
1443  
1444  		reg[6] = (src_reg[6]|0x04);
1445  		memcpy(tmp_reg,reg,REG_LENGTH);
1446  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1447  		cgsleep_ms(1); //usleep(200);
1448  
1449  		//Step6: high tsadc_en
1450  		reg[7] = (src_reg[7]|0x20);
1451  		memcpy(tmp_reg,reg,REG_LENGTH);
1452  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1453  		cgsleep_ms(1); //usleep(200);
1454  
1455  		//Step7: tsadc_ana_reg_9 = 0;tsadc_ana_reg_8  = 0
1456  		reg[5] = (src_reg[5]&0xfc);
1457  		memcpy(tmp_reg,reg,REG_LENGTH);
1458  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1459  		cgsleep_ms(1); //usleep(200);
1460  
1461  		//Step8: tsadc_ana_reg_7 = 1;tsadc_ana_reg_1 = 0
1462  		reg[6] = (src_reg[6]&0x7d);
1463  		memcpy(tmp_reg,reg,REG_LENGTH);
1464  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1465  		cgsleep_ms(1); //usleep(200);
1466  	}
1467  	else
1468  	{
1469  		//configure for vsensor
1470  		reg[7] = (src_reg[7]&0x7f);
1471  		memcpy(tmp_reg,reg,REG_LENGTH);
1472  
1473  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1474  		cgsleep_ms(1); //usleep(200);
1475  		reg[7] = (src_reg[7]|0x80);
1476  		memcpy(tmp_reg,reg,REG_LENGTH);
1477  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1478  		cgsleep_ms(1); //usleep(200);
1479  
1480  		reg[6] = (src_reg[6]|0x04);
1481  		memcpy(tmp_reg,reg,REG_LENGTH);
1482  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1483  		cgsleep_ms(1); //usleep(200);
1484  
1485  		//Step6: high tsadc_en
1486  		reg[7] = (src_reg[7]|0x20);
1487  		memcpy(tmp_reg,reg,REG_LENGTH);
1488  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1489  		cgsleep_ms(1); //usleep(200);
1490  
1491  		//Step7: tsadc_ana_reg_9 = 0;tsadc_ana_reg_8  = 0
1492  		reg[5] = ((src_reg[5]|0x01)&0xfd);
1493  		memcpy(tmp_reg,reg,REG_LENGTH);
1494  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1495  		cgsleep_ms(1); //usleep(200);
1496  
1497  		//Step8: tsadc_ana_reg_7 = 1;tsadc_ana_reg_1 = 0
1498  		reg[6] = ((src_reg[6]|0x02)&0x7f);
1499  		memcpy(tmp_reg,reg,REG_LENGTH);
1500  		mcompat_cmd_write_register(chain_id,chip_id,tmp_reg,REG_LENGTH);
1501  		cgsleep_ms(1); //usleep(200);
1502  	}
1503  }
1504  
1505  void  mcompat_cfg_tsadc_divider(int chain_id,unsigned int pll_clk)
1506  {
1507  	unsigned int tsadc_divider_tmp;
1508  	unsigned char  tsadc_divider;
1509  	unsigned char  buffer[64] = {0x02,0x50,0xa0,0x06,0x28,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
1510  	unsigned char  readbuf[32] = {0};
1511  
1512  	tsadc_divider_tmp = (pll_clk/2)*1000/16/650;
1513  	tsadc_divider = (unsigned char)(tsadc_divider_tmp & 0xff);
1514  	buffer[5] = 0x00 | tsadc_divider;
1515  
1516  	if (!mcompat_cmd_read_write_reg0d(chain_id, 0x00, buffer, REG_LENGTH, readbuf))
1517  	{
1518  		applog(LOG_DEBUG,"Write t/v sensor Value Failed!");
1519  	}
1520  	else
1521  	{
1522  		applog(LOG_DEBUG,"Write t/v sensor Value Success!");
1523  	}
1524  }
1525  
1526  double mcompat_get_average_volt(int *volt, int size)
1527  {
1528  	int i;
1529  	int count = 0;
1530  	int total = 0, max = 0, min = 1000;
1531  
1532  	for (i = 0; i < size; i++) {
1533  		if (volt[i] > 0) {
1534  			total += volt[i];
1535  			max = MAX(max, volt[i]);
1536  			min = MIN(min, volt[i]);
1537  			count++;
1538  		}
1539  	}
1540  
1541  	if (count > 2)
1542  		return (double) (total - max - min) / (count - 2);
1543  	else
1544  		return 0;
1545  }
1546  
1547  /* Adjust vid till we are just above volt_target. We should have already set
1548   * vid_start before calling this function. */
1549  int mcompat_find_chain_vid(int chain_id, int chip_num, int vid_start, double volt_target)
1550  {
1551  	int chip_volt[MCOMPAT_CONFIG_MAX_CHIP_NUM] = {0};
1552  	int vid = vid_start;
1553  	double volt_avg;
1554  
1555  	mcompat_cfg_tsadc_divider(chain_id, 120);
1556  	cgsleep_ms(1);
1557  
1558  	mcompat_configure_tvsensor(chain_id, CMD_ADDR_BROADCAST, 0);
1559  	cgsleep_ms(1);
1560  
1561  	applog(LOG_NOTICE, "chain%d find_chain_vid: start_vid = %d, target_volt = %.1f",
1562  		chain_id, vid_start, volt_target);
1563  
1564  	mcompat_get_chip_volt(chain_id, chip_volt);
1565  	volt_avg = mcompat_get_average_volt(chip_volt, chip_num);
1566  	applog(LOG_NOTICE, "Chain %d VID %d voltage %.1f", chain_id, vid, volt_avg);
1567  
1568  	/* Go down voltage till we're below the target */
1569  	while (volt_avg >= volt_target) {
1570  		if (vid >= VID_MAX) {
1571  			applog(LOG_WARNING, "Chain %d unable to get below target voltage %.1f by VID %d",
1572  			       chain_id, volt_target, vid);
1573  			break;
1574  		}
1575  		vid++;
1576  		mcompat_set_vid(chain_id, vid);
1577  		mcompat_get_chip_volt(chain_id, chip_volt);
1578  		volt_avg = mcompat_get_average_volt(chip_volt, chip_num);
1579  		applog(LOG_NOTICE, "Chain %d VID %d voltage %.1f", chain_id, vid, volt_avg);
1580  	}
1581  	cgsleep_ms(500);
1582  
1583  	mcompat_get_chip_volt(chain_id, chip_volt);
1584  	volt_avg = mcompat_get_average_volt(chip_volt, chip_num);
1585  	applog(LOG_NOTICE, "Chain %d VID %d voltage %.1f", chain_id, vid, volt_avg);
1586  
1587  	/* Now go down VID till we're above the target, final point should
1588  	 * be closest without going below voltage */
1589  	while (volt_avg < volt_target) {
1590  		if (vid <= VID_MIN) {
1591  			applog(LOG_WARNING, "Chain %d unable to get above target voltage %.1f by VID %d",
1592  			       chain_id, volt_target, vid);
1593  			break;
1594  		}
1595  		vid--;
1596  		mcompat_set_vid(chain_id, vid);
1597  		cgsleep_ms(500);
1598  		mcompat_get_chip_volt(chain_id, chip_volt);
1599  		volt_avg = mcompat_get_average_volt(chip_volt, chip_num);
1600  		applog(LOG_NOTICE, "Chain %d VID %d voltage %.1f", chain_id, vid, volt_avg);
1601  	}
1602  
1603  	mcompat_configure_tvsensor(chain_id, CMD_ADDR_BROADCAST, 1);
1604  
1605  	return vid;
1606  }
1607  
1608  
1609  #define IOCTL_SET_VAL_0                         _IOR(MAGIC_NUM, 0, char *)
1610  #define IOCTL_SET_VALUE_0                       _IOR(MAGIC_NUM, 0, char *)
1611  #define IOCTL_SET_CHAIN_0                       _IOR(MAGIC_NUM, 1, char *)
1612  
1613  #define BUF_MAX                                 (256)
1614  
1615  #define SYSFS_GPIO_EXPORT                       ("/sys/class/gpio/export")
1616  #define SYSFS_GPIO_DIR_STR                      ("/sys/class/gpio/gpio%d/direction")
1617  #define SYSFS_GPIO_VAL_STR                      ("/sys/class/gpio/gpio%d/value")
1618  #define SYSFS_GPIO_DIR_OUT                      ("out")
1619  #define SYSFS_GPIO_DIR_IN                       ("in")
1620  #define SYSFS_GPIO_VAL_LOW                      ("0")
1621  #define SYSFS_GPIO_VAL_HIGH                     ("1")
1622  
1623  void zynq_gpio_init(int pin, int dir)
1624  {
1625  	int fd = 0;
1626  	ssize_t write_bytes = 0;
1627  	char fvalue[BUF_MAX] = {'\0'};
1628  	char fpath[BUF_MAX] = {'\0'};
1629  
1630  	fd = open(SYSFS_GPIO_EXPORT, O_WRONLY);
1631  	if (-1 == fd)
1632  	{
1633  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1634  	}
1635  	memset(fvalue, 0, sizeof(fvalue));
1636  	sprintf(fvalue, "%d", pin);
1637  	write_bytes = write(fd, fvalue, strlen(fvalue));
1638  	if (-1 == write_bytes)
1639  	{
1640  		if (EBUSY == errno)
1641  		{
1642  			close(fd);
1643  			return;
1644  		}
1645  		else
1646  		{
1647  			applog(LOG_ERR, "%s,%d: %d,%s.", __FILE__, __LINE__, errno, strerror(errno));
1648  		}
1649  	}
1650  	close(fd);
1651  
1652  	memset(fpath, 0, sizeof(fpath));
1653  	sprintf(fpath, SYSFS_GPIO_DIR_STR, pin);
1654  	fd = open(fpath, O_WRONLY);
1655  	if (-1 == fd)
1656  	{
1657  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1658  	}
1659  	if (0 == dir)
1660  	{
1661  		write_bytes = write(fd, SYSFS_GPIO_DIR_OUT, sizeof(SYSFS_GPIO_DIR_OUT));
1662  		if (-1 == write_bytes)
1663  		{
1664  			applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1665  		}
1666  	}
1667  	else
1668  	{
1669  		write_bytes = write(fd, SYSFS_GPIO_DIR_IN, sizeof(SYSFS_GPIO_DIR_IN));
1670  		if (-1 == write_bytes)
1671  		{
1672  			applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1673  		}
1674  	}
1675  	close(fd);
1676  
1677  	return;
1678  }
1679  
1680  static bool zynq_gpio_write(int pin, int val)
1681  {
1682  	int  fd = 0;
1683  	ssize_t  write_bytes = 0;
1684  	char fpath[BUF_MAX] = {'\0'};
1685  	bool ret = false;
1686  
1687  	memset(fpath, 0, sizeof(fpath));
1688  	sprintf(fpath, SYSFS_GPIO_VAL_STR, pin);
1689  	fd = open(fpath, O_WRONLY);
1690  	if (-1 == fd) {
1691  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1692  		goto out;
1693  	}
1694  
1695  	if (0 == val) {
1696  		write_bytes = write(fd, SYSFS_GPIO_VAL_LOW, sizeof(SYSFS_GPIO_VAL_LOW));
1697  		if (-1 == write_bytes) {
1698  			applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1699  			goto out_close;
1700  		}
1701  	} else {
1702  		write_bytes = write(fd, SYSFS_GPIO_VAL_HIGH, sizeof(SYSFS_GPIO_VAL_HIGH));
1703  		if (-1 == write_bytes) {
1704  			applog(LOG_ERR, "%s,%d: %s,%s.", __FILE__, __LINE__, fpath, strerror(errno));
1705  			goto out_close;
1706  		}
1707  	}
1708  	ret = true;
1709  out_close:
1710  	close(fd);
1711  out:
1712  	return ret;
1713  }
1714  
1715  int zynq_gpio_read(int pin)
1716  {
1717  	int  fd = 0;
1718  	int  val = 0;
1719  	ssize_t read_bytes = 0;
1720  	char fpath[BUF_MAX] = {'\0'};
1721  	char fvalue[BUF_MAX] = {'\0'};
1722  
1723  	memset(fpath, 0, sizeof(fpath));
1724  	sprintf(fpath, SYSFS_GPIO_VAL_STR, pin);
1725  	fd = open(fpath, O_RDONLY);
1726  	if (-1 == fd)
1727  	{
1728  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1729  	}
1730  	memset(fvalue, 0, sizeof(fvalue));
1731  	read_bytes = read(fd, fvalue, 1);
1732  	if (-1 == read_bytes)
1733  	{
1734  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1735  	}
1736  	close(fd);
1737  
1738  	if ('0' == fvalue[0])
1739  	{
1740  		val = 0;
1741  	}
1742  	else if ('1' == fvalue[0])
1743  	{
1744  		val = 1;
1745  	}
1746  	else
1747  	{
1748  		val = -1;
1749  	}
1750  
1751  	return val;
1752  }
1753  
1754  void zynq_gpio_exit(int __maybe_unused pin)
1755  {
1756  	return;
1757  }
1758  
1759  pthread_mutex_t s_pwm_lock;
1760  
1761  
1762  void zynq_set_pwm(unsigned char fan_id, int frequency, int duty)
1763  {
1764  	int fd = 0;
1765  	int duty_driver = 0;
1766  
1767  	duty_driver = frequency / 100 * (100 - duty);
1768  
1769  	//pthread_mutex_lock(&s_pwm_lock);
1770  
1771  	fd = open(SYSFS_PWM_DEV, O_RDWR);
1772  	if (fd < 0)
1773  	{
1774  		applog(LOG_ERR, "open %s fail", SYSFS_PWM_DEV);
1775  		//pthread_mutex_unlock(&s_pwm_lock);
1776  		return;
1777  	}
1778  
1779  	if (ioctl(fd, IOCTL_SET_PWM_FREQ(fan_id), frequency) < 0)
1780  	{
1781  		applog(LOG_ERR,"set fan%d frequency fail ", fan_id);
1782  		close(fd);
1783  		//pthread_mutex_unlock(&s_pwm_lock);
1784  		return ;
1785  	}
1786  
1787  	if (ioctl(fd, IOCTL_SET_PWM_DUTY(fan_id), duty_driver) < 0)
1788  	{
1789  		applog(LOG_ERR,"set fan%d duty fail ", fan_id);
1790  		close(fd);
1791  		//pthread_mutex_unlock(&s_pwm_lock);
1792  		return ;
1793  	}
1794  
1795  	close(fd);
1796  	//pthread_mutex_unlock(&s_pwm_lock);
1797  
1798  	return;
1799  }
1800  
1801  #define BUF_MAX                     (256)
1802  
1803  #define DEV_TEMPLATE                ("/dev/spidev%d.%d")
1804  #define SYSFS_EXPORT                ("/sys/devices/soc0/amba/f8007000.devcfg/fclk_export")
1805  #define SYSFS_VAL_STR               ("/sys/devices/soc0/amba/f8007000.devcfg/fclk/fclk1/set_rate")
1806  
1807  static void zynq_spi_clock_init(void);
1808  
1809  void zynq_spi_init(ZYNQ_SPI_T *spi, int bus)
1810  {
1811  	char dev_fname[BUF_MAX] = {'\0'};
1812  	int fd = 0;
1813  	uint8_t mode   = MCOMPAT_CONFIG_SPI_DEFAULT_MODE;
1814  	uint32_t speed = MCOMPAT_CONFIG_SPI_DEFAULT_SPEED;
1815  	uint8_t bits   = MCOMPAT_CONFIG_SPI_DEFAULT_BITS_PER_WORD;
1816  
1817  	zynq_spi_clock_init();
1818  	zynq_set_spi_speed(MCOMPAT_CONFIG_SPI_DEFAULT_SPEED);
1819  
1820  	sprintf(dev_fname, DEV_TEMPLATE, bus, MCOMPAT_CONFIG_SPI_DEFAULT_CS_LINE);
1821  	fd = open(dev_fname, O_RDWR);
1822  	if (-1 == fd)
1823  	{
1824  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1825  	}
1826  
1827  	if (ioctl(fd, SPI_IOC_WR_MODE, &mode) < 0)
1828  	{
1829  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1830  	}
1831  	if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0)
1832  	{
1833  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1834  	}
1835  	if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0)
1836  	{
1837  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1838  	}
1839  	if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0)
1840  	{
1841  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1842  	}
1843  	if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0)
1844  	{
1845  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1846  	}
1847  	if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0)
1848  	{
1849  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1850  	}
1851  
1852  	spi->fd = fd;
1853  	pthread_mutex_init(&(spi->lock), NULL);
1854  
1855  	applog(LOG_DEBUG, "SPI '%s': mode=%hhu, bits=%hhu, speed=%u ",
1856  		    dev_fname, MCOMPAT_CONFIG_SPI_DEFAULT_MODE, MCOMPAT_CONFIG_SPI_DEFAULT_BITS_PER_WORD, MCOMPAT_CONFIG_SPI_DEFAULT_SPEED);
1857  	return;
1858  }
1859  
1860  void zynq_spi_exit(ZYNQ_SPI_T *spi)
1861  {
1862  	if (NULL == spi)
1863  	{
1864  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1865  	}
1866  
1867  	close(spi->fd);
1868  
1869  	return;
1870  }
1871  
1872  void zynq_spi_write(ZYNQ_SPI_T *spi, uint8_t *txbuf, int len)
1873  {
1874  	pthread_mutex_lock(&(spi->lock));
1875  
1876  	if ((len <= 0) || (txbuf == NULL))
1877  	{
1878  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1879  	}
1880  
1881  	if (write(spi->fd, txbuf, len) <= 0)
1882  	{
1883  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1884  	}
1885  
1886  	pthread_mutex_unlock(&spi->lock);
1887  	return;
1888  }
1889  
1890  void zynq_spi_read(ZYNQ_SPI_T *spi, uint8_t *rxbuf, int len)
1891  {
1892  	pthread_mutex_lock(&(spi->lock));
1893  
1894  	if ((len <= 0) || (rxbuf == NULL))
1895  	{
1896  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1897  	}
1898  
1899  	if (read(spi->fd, rxbuf, len) <= 0)
1900  	{
1901  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1902  	}
1903  
1904  	pthread_mutex_unlock(&spi->lock);
1905  	return;
1906  }
1907  
1908  void zynq_spi_clock_init(void)
1909  {
1910  	int  fd = 0;
1911  	ssize_t write_bytes = 0;
1912  	char fvalue[BUF_MAX] = {'\0'};
1913  
1914  	fd = access(SYSFS_VAL_STR, F_OK);
1915  	if (0 == fd)
1916  	{
1917  		return;
1918  	}
1919  
1920  	fd = open(SYSFS_EXPORT, O_WRONLY);
1921  	if (-1 == fd)
1922  	{
1923  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1924  	}
1925  	memset(fvalue, 0, sizeof(fvalue));
1926  	sprintf(fvalue, "%s", "fclk1");
1927  	write_bytes = write(fd, fvalue, strlen(fvalue));
1928  	if (-1 == write_bytes)
1929  	{
1930  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1931  	}
1932  	close(fd);
1933  
1934  	return;
1935  }
1936  
1937  void zynq_set_spi_speed(int speed)
1938  {
1939  	int  fd = 0;
1940  	ssize_t write_bytes = 0;
1941  	char fvalue[BUF_MAX] = {'\0'};
1942  
1943  	applog(LOG_DEBUG, "set spi speed %d ", speed);
1944  	fd = open(SYSFS_VAL_STR, O_WRONLY);
1945  	if (-1 == fd)
1946  	{
1947  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1948  	}
1949  	memset(fvalue, 0, sizeof(fvalue));
1950  	sprintf(fvalue, "%d", speed * 16);
1951  	write_bytes = write(fd, fvalue, strlen(fvalue));
1952  	if (-1 == write_bytes)
1953  	{
1954  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1955  	}
1956  	close(fd);
1957  
1958  	return;
1959  }
1960  
1961  int zynq_gpio_g9_vid_set(int level)
1962  {
1963  	int fd = 0;
1964  
1965  	fd = open(SYSFS_VID_DEV, O_RDWR);
1966  	if (-1 == fd)
1967  	{
1968  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1969  	}
1970  
1971  	if (ioctl(fd, IOCTL_SET_VAL_0, 0x0100 | level) < 0)
1972  	{
1973  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1974  	}
1975  	close(fd);
1976  
1977  	return 0;
1978  }
1979  
1980  int zynq_gpio_g19_vid_set(int chain_id, int level)
1981  {
1982  	int fd = 0;
1983  
1984  	fd = open(SYSFS_VID_DEV, O_RDWR);
1985  	if (-1 == fd)
1986  	{
1987  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1988  	}
1989  	if (ioctl(fd, IOCTL_SET_CHAIN_0, chain_id) < 0)
1990  	{
1991  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1992  	}
1993  	if (ioctl(fd, IOCTL_SET_VALUE_0, 0x100 | level) < 0)
1994  	{
1995  		applog(LOG_ERR, "%s,%d: %s.", __FILE__, __LINE__, strerror(errno));
1996  	}
1997  	close(fd);
1998  
1999  	return 0;
2000  }
2001  
2002  /* DUPES, FIXME THIS ONE IS USED */
2003  typedef struct HUB_DEV_TAG {
2004  	volatile uint8_t *vir_base;
2005  	uint32_t          phy_addr;
2006  	uint32_t          mem_size;
2007  	const char       *name;
2008  } HUB_DEV_T;
2009  
2010  static HUB_DEV_T s_dev_list[] = {
2011  	{NULL, 0x43C30000, 0x2000, "spi"},
2012  	{NULL, 0x43C00000, 0x1000, "peripheral"},
2013  	//{NULL, 0x43C32000, 0x1000, "sha256"},
2014  };
2015  
2016  #if 0
2017  /* DUPES FIXME THIS ONE ISN'T USED */
2018  typedef struct HUB_DEV_TAG {
2019  volatile uint8_t *vir_base;
2020  uint32_t          phy_addr;
2021  const char       *name;
2022  } HUB_DEV_T;
2023  
2024  static HUB_DEV_T s_dev_list[] = {
2025  {NULL, 0x43C30000, "spi"},
2026  {NULL, 0x43C10000, "peripheral"},
2027  {NULL, 0x43C00000, "fans"},
2028  {NULL, 0x41200000, "gpio"},
2029  {NULL, 0x43C32000, "sha256"},
2030  };
2031  #endif
2032  
2033  void hub_hardware_init(void)
2034  {
2035  	int fd = 0;
2036  	int i = 0;
2037  	int iMax = sizeof(s_dev_list) / sizeof(s_dev_list[0]);
2038  
2039  	applog(LOG_INFO, "max range: 0x%x.", _MAX_MEM_RANGE);
2040  
2041  	fd = open("/dev/mem", O_RDWR | O_SYNC);
2042  	if (-1 == fd)
2043  	{
2044  		applog(LOG_ERR, "open /dev/mem:");
2045  		return;
2046  	}
2047  
2048  	applog(LOG_INFO, "total: %d dev will mmap.", iMax);
2049  	for(i = 0; i < iMax; i++)
2050  	{
2051  		s_dev_list[i].vir_base = mmap(NULL, _MAX_MEM_RANGE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, s_dev_list[i].phy_addr);
2052  		if (MAP_FAILED == s_dev_list[i].vir_base)
2053  		{
2054  			close(fd);
2055  			applog(LOG_ERR, "mmap %s:phy:0x%08x => vir:%p fail.", s_dev_list[i].name, s_dev_list[i].phy_addr, s_dev_list[i].vir_base);
2056  			return;
2057  		}
2058  
2059  		applog(LOG_INFO, "mmap %s:phy:0x%08x => vir:%p ok.", s_dev_list[i].name, s_dev_list[i].phy_addr, s_dev_list[i].vir_base);
2060  	}
2061  
2062  	applog(LOG_INFO, "total: %d dev mmap done.", iMax);
2063  
2064  	close(fd);
2065  }
2066  
2067  void hub_hardware_deinit(void)
2068  {
2069  	int i = 0;
2070  	int iMax = sizeof(s_dev_list) / sizeof(s_dev_list[0]);
2071  
2072  	for(i = 0; i < iMax; i++)
2073  	{
2074  		munmap((void *)s_dev_list[i].vir_base, _MAX_MEM_RANGE);
2075  		applog(LOG_INFO, "unmap %s:vir:%p.", s_dev_list[i].name, s_dev_list[i].vir_base);
2076  	}
2077  }
2078  
2079  /*  vid, iic, uart */
2080  // compatible values for different vid types
2081  static int s_vid_map[][3] = {
2082  	{0,  1608, 54},
2083  	{1,  1599, 60},
2084  	{2,  1590, 67},
2085  	{3,  1581, 73},
2086  	{4,  1572, 80},
2087  	{5,  1563, 86},
2088  	{6,  1554, 93},
2089  	{7,  1545, 99},
2090  	{8,  1536, 106},
2091  	{9,  1527, 112},
2092  	{10, 1518, 119},
2093  	{11, 1509, 125},
2094  	{12, 1500, 132},
2095  	{13, 1491, 138},
2096  	{14, 1482, 145},
2097  	{15, 1473, 151},
2098  	{16, 1464, 158},
2099  	{17, 1455, 164},
2100  	{18, 1446, 171},
2101  	{19, 1437, 177},
2102  	{20, 1428, 184},
2103  	{21, 1419, 190},
2104  	{22, 1410, 197},
2105  	{23, 1401, 203},
2106  	{24, 1392, 210},
2107  	{25, 1383, 216},
2108  	{26, 1374, 223},
2109  	{27, 1365, 229},
2110  	{28, 1356, 236},
2111  	{29, 1347, 242},
2112  	{30, 1338, 248},
2113  	{31, 1329, 255},
2114  };
2115  
2116  static bool hub_set_vid_i2c(uint8_t chain_id, int vid);
2117  static bool hub_set_vid_uart(uint8_t chain_id, int vid);
2118  static void send_uart(const char *path, char byte);
2119  static bool set_vol_on_i2c(int chain, int vol);
2120  static bool set_power_on_i2c(int chain, int val);
2121  
2122  bool hub_set_vid(uint8_t chain_id, int vol)
2123  {
2124  	int type = 0;
2125  
2126  	type = misc_get_vid_type();
2127  	switch(type)
2128  	{
2129  		case MCOMPAT_LIB_VID_VID_TYPE:
2130  		{
2131  			hub_set_vid_vid(chain_id, vol);
2132  			return true;
2133  		}
2134  
2135  		case MCOMPAT_LIB_VID_I2C_TYPE:
2136  		{
2137  			if (hub_set_vid_i2c(chain_id, vol))
2138  			{
2139  				return true;
2140  			}
2141  			else
2142  			{
2143  				return false;
2144  			}
2145  		}
2146  
2147  		case MCOMPAT_LIB_VID_UART_TYPE:
2148  		{
2149  			if (hub_set_vid_uart(chain_id, vol))
2150  			{
2151  				return true;
2152  			}
2153  			else
2154  			{
2155  				return false;
2156  			}
2157  		}
2158  
2159  		case MCOMPAT_LIB_VID_GPIO_I2C_TYPE:
2160  		{
2161  			applog(LOG_ERR, "%s,%d:no impl type:MCOMPAT_LIB_VID_GPIO_I2C_TYPE.", __FILE__, __LINE__);
2162  			break;
2163  		}
2164  
2165  		default:
2166  		{
2167  			applog(LOG_ERR, "%s,%d:err vid type:%d.", __FILE__, __LINE__, type);
2168  			break;
2169  		}
2170  	}
2171  
2172  	return true;
2173  }
2174  
2175  static bool hub_set_vid_i2c(uint8_t chan_id, int vid)
2176  {
2177  	int vol = s_vid_map[vid][1];
2178  
2179  	set_vol_on_i2c(chan_id + 1 , vol);
2180  
2181  	return true;
2182  }
2183  
2184  static bool hub_set_vid_uart(uint8_t chain_id, int vid)
2185  {
2186  	char byte = 0;
2187  	byte = (char)s_vid_map[vid][2];
2188  
2189  	hub_set_vid_uart_select(chain_id);
2190  
2191  	send_uart("/dev/ttyPS1", byte);
2192  
2193  	return true;
2194  }
2195  
2196  static void hub_set_power_en_i2c(uint8_t chain_id,int value)
2197  {
2198  	set_power_on_i2c(chain_id + 1, value);
2199  }
2200  
2201  bool set_timeout_on_i2c(int time)
2202  {
2203  	int i;
2204  	int fd;
2205  	int sum = 0;
2206  	unsigned char buffer[10] = {0};
2207  	struct i2c_rdwr_ioctl_data packets;
2208  	struct i2c_msg messages[2];
2209  
2210  	fd = open(I2C_DEVICE_NAME, O_RDWR);
2211  	if(fd < 0) {
2212  		applog(LOG_ERR, "%s,%d:open %s failled: %d.", __FILE__, __LINE__, I2C_DEVICE_NAME, errno);
2213  		return false;
2214  	}
2215  
2216  	buffer[0] = 0x00;
2217  	buffer[1] = 0xab;
2218  	buffer[2] = 0x00;
2219  	buffer[3] = 0x70;
2220  	buffer[4] = 0x00;
2221  	buffer[5] = 0x01;
2222  	buffer[6] = (time/30);
2223  	for (i = 0; i < 7; i++)
2224  		sum = sum + buffer[i];
2225  	buffer[7] = sum & 0xff;
2226  	buffer[8] = 0xcd;
2227  
2228  	messages[0].addr  = I2C_SLAVE_ADDR;
2229  	messages[0].flags = I2C_M_IGNORE_NAK;
2230  	messages[0].len   = sizeof(buffer);
2231  	messages[0].buf   = buffer;
2232  
2233  	packets.msgs      = messages;
2234  	packets.nmsgs     = 1;
2235  
2236  	if(ioctl(fd, I2C_RDWR, &packets) < 0) {
2237  		applog(LOG_ERR, "%s,%d:write iic failled: %d.", __FILE__, __LINE__, errno);
2238  		close(fd);
2239  		return false;
2240  	}
2241  
2242  	close(fd);
2243  	return true;
2244  }
2245  
2246  static bool set_power_on_i2c(int chain, int val)
2247  {
2248  	int i;
2249  	int fd;
2250  	int sum = 0;
2251  	unsigned char buffer[10] = {0};
2252  	struct i2c_rdwr_ioctl_data packets;
2253  	struct i2c_msg messages[2];
2254  
2255  	fd = open(I2C_DEVICE_NAME, O_RDWR);
2256  	if(fd < 0) {
2257  		applog(LOG_ERR, "%s,%d:open %s failled: %d.", __FILE__, __LINE__, I2C_DEVICE_NAME, errno);
2258  		return false;
2259  	}
2260  
2261  	buffer[0] = 0x00;
2262  	buffer[1] = 0xab;
2263  	buffer[2] = 0x00;
2264  	buffer[3] = 0x85;
2265  	buffer[4] = 0x00;
2266  	buffer[5] = 0x02;
2267  	buffer[6] = chain;
2268  	if(val != 0)
2269  		buffer[7] = 0x01;
2270  	else
2271  		buffer[7] = 0x02;
2272  
2273  	for (i = 0; i < 8; i++)
2274  		sum = sum + buffer[i];
2275  	buffer[8] = sum & 0xff;
2276  	buffer[9] = 0xcd;
2277  
2278  	messages[0].addr  = I2C_SLAVE_ADDR;
2279  	messages[0].flags = I2C_M_IGNORE_NAK;
2280  	messages[0].len   = sizeof(buffer);
2281  	messages[0].buf   = buffer;
2282  
2283  	packets.msgs      = messages;
2284  	packets.nmsgs     = 1;
2285  
2286  	if(ioctl(fd, I2C_RDWR, &packets) < 0) {
2287  		applog(LOG_ERR, "%s,%d:write iic failled: %d.", __FILE__, __LINE__, errno);
2288  		close(fd);
2289  		return false;
2290  	}
2291  
2292  	close(fd);
2293  	return true;
2294  }
2295  
2296  static bool set_vol_on_i2c(int chain, int vol)
2297  {
2298  	int i;
2299  	int fd;
2300  	int sum = 0;
2301  	unsigned char buffer[12] = {0};
2302  	struct i2c_rdwr_ioctl_data packets;
2303  	struct i2c_msg messages[2];
2304  
2305  	fd = open(I2C_DEVICE_NAME, O_RDWR);
2306  	if (fd < 0)
2307  	{
2308  		applog(LOG_ERR, "%s,%d:open %s failled: %d.", __FILE__, __LINE__, I2C_DEVICE_NAME, errno);
2309  		return false;
2310  	}
2311  
2312  	buffer[0] = 0x00;
2313  	buffer[1] = 0xab;
2314  	buffer[2] = 0x00;
2315  	buffer[3] = 0x83;
2316  	buffer[4] = 0x00;
2317  	buffer[5] = 0x04;
2318  	buffer[6] = chain;
2319  	buffer[7] = 0x00;
2320  	buffer[8] = ((vol >> 0) & 0xff);
2321  	buffer[9] = ((vol >> 8) & 0xff);
2322  
2323  	for(i=0; i<10; i++){
2324  		sum = sum + buffer[i];
2325  	}
2326  	buffer[10] = sum & 0xff;
2327  	buffer[11] = 0xcd;
2328  
2329  	messages[0].addr  = I2C_SLAVE_ADDR;
2330  	messages[0].flags = I2C_M_IGNORE_NAK;
2331  	messages[0].len   = sizeof(buffer);
2332  	messages[0].buf   = buffer;
2333  
2334  	packets.msgs      = messages;
2335  	packets.nmsgs     = 1;
2336  
2337  	if (ioctl(fd, I2C_RDWR, &packets) < 0) {
2338  		applog(LOG_ERR, "%s,%d:write iic failled: %d.", __FILE__, __LINE__, errno);
2339  		close(fd);
2340  		return false;
2341  	}
2342  
2343  	close(fd);
2344  	return true;
2345  }
2346  
2347  static void send_uart(const char *path, char byte)
2348  {
2349  	int tty_fd = 0;
2350  	int rst = 0;
2351  	char buf[5] = {0};
2352  
2353  	tty_fd = open(path, O_WRONLY);
2354  	if (-1 == tty_fd)
2355  	{
2356  		applog(LOG_ERR, "%s,%d:open %s failled: %d.", __FILE__, __LINE__, path, errno);
2357  	}
2358  	/* applog(LOG_DEBUG, "%s,%d.", __FILE__, __LINE__); */
2359  
2360  	buf[0] = 0xaa;
2361  	buf[1] = 0x2;
2362  	buf[2] = 0x1;
2363  	buf[3] = byte;
2364  	buf[4] = (~(buf[1]+buf[2]+buf[3]))+1;
2365  	rst = write(tty_fd, &buf, 5);
2366  	if (-1 == rst)
2367  	{
2368  		close(tty_fd);
2369  		applog(LOG_ERR, "%s,%d:write tty failled: %d.", __FILE__, __LINE__, errno);
2370  	}
2371  
2372  	/* for debug */
2373  	#if 0
2374  	int i = 0;
2375  	applog(LOG_DEBUG, "uart %s send:", path);
2376  	for(i = 0; i < 5; i++)
2377  	{
2378  	applog(LOG_DEBUG, "%02X,", buf[i]);
2379  }
2380  applog(LOG_DEBUG, "");
2381  #endif
2382  
2383  close(tty_fd);
2384  
2385  return;
2386  }
2387  
2388  #if 0
2389  #ifdef SYSTEM_LINUX
2390  static void hub_hardware_init(void)
2391  {
2392  int fd = 0;
2393  int i = 0;
2394  int iMax = sizeof(s_dev_list) / sizeof(s_dev_list[0]);
2395  
2396  applog(LOG_INFO, "max range: 0x%x.", PAGE_SIZE);
2397  
2398  fd = open("/dev/mem", O_RDWR | O_SYNC);
2399  if (-1 == fd)
2400  {
2401  applog(LOG_ERR, "open /dev/mem:");
2402  return;
2403  }
2404  
2405  applog(LOG_INFO, "total: %d dev will mmap.", iMax);
2406  for(i = 0; i < iMax; i++)
2407  {
2408  s_dev_list[i].vir_base = mmap(NULL, s_dev_list[i].mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, s_dev_list[i].phy_addr);
2409  if (MAP_FAILED == s_dev_list[i].vir_base)
2410  {
2411  close(fd);
2412  applog(LOG_ERR, "mmap %s:phy:0x%08x => vir:%p size:0x%x fail.", s_dev_list[i].name, s_dev_list[i].phy_addr, s_dev_list[i].vir_base, s_dev_list[i].mem_size);
2413  return;
2414  }
2415  
2416  applog(LOG_INFO, "mmap %s:phy:0x%08x => vir:%p size:0x%x ok.", s_dev_list[i].name, s_dev_list[i].phy_addr, s_dev_list[i].vir_base, s_dev_list[i].mem_size);
2417  }
2418  
2419  applog(LOG_INFO, "total: %d dev mmap done.", iMax);
2420  
2421  close(fd);
2422  }
2423  
2424  static void hub_hardware_deinit(void)
2425  {
2426  int i = 0;
2427  int iMax = sizeof(s_dev_list) / sizeof(s_dev_list[0]);
2428  
2429  for(i = 0; i < iMax; i++)
2430  {
2431  munmap((void *)s_dev_list[i].vir_base, s_dev_list[i].mem_size);
2432  applog(LOG_INFO, "unmap %s:vir:%p.", s_dev_list[i].name, s_dev_list[i].vir_base);
2433  }
2434  }
2435  
2436  
2437  #endif
2438  #endif
2439  
2440  void hub_init(void)
2441  {
2442  	hub_hardware_init();
2443  }
2444  
2445  void hub_deinit(void)
2446  {
2447  	hub_hardware_deinit();
2448  }
2449  
2450  #define INDEX_SPI           0
2451  #define INDEX_PERIPHERAL    1
2452  #define INDEX_SHA256        2
2453  
2454  
2455  // for peripheral ip
2456  void Xil_Peripheral_Out32(uint32_t phyaddr, uint32_t val)
2457  {
2458  	uint32_t pgoffset = phyaddr & ((uint32_t)(s_dev_list[INDEX_PERIPHERAL].mem_size -1));
2459  	pgoffset = phyaddr;
2460  
2461  	#ifdef SYSTEM_LINUX
2462  	// for software team
2463  	*(volatile uint32_t *)(s_dev_list[INDEX_PERIPHERAL].vir_base + pgoffset) = val;
2464  	#else
2465  	// for digit team
2466  	*(volatile uint32_t *)(s_dev_list[INDEX_PERIPHERAL].phy_addr + pgoffset) = val;
2467  	#endif
2468  }
2469  
2470  int Xil_Peripheral_In32(uint32_t phyaddr)
2471  {
2472  	uint32_t val;
2473  	uint32_t pgoffset = phyaddr & ((uint32_t)(s_dev_list[INDEX_PERIPHERAL].mem_size -1));
2474  	pgoffset = phyaddr;
2475  
2476  	#ifdef SYSTEM_LINUX
2477  	// for software team
2478  	val = *(volatile uint32_t *)(s_dev_list[INDEX_PERIPHERAL].vir_base + pgoffset);
2479  	#else
2480  	// for digit team
2481  	val = *(volatile uint32_t *)(s_dev_list[INDEX_PERIPHERAL].phy_addr + pgoffset);
2482  	#endif
2483  
2484  	return val;
2485  }
2486  
2487  // for spi ip
2488  void Xil_SPI_Out32(uint32_t phyaddr, uint32_t val)
2489  {
2490  	uint32_t pgoffset = phyaddr & ((uint32_t)(s_dev_list[INDEX_SPI].mem_size -1));
2491  
2492  	#ifdef SYSTEM_LINUX
2493  	// for software team
2494  	*(volatile uint32_t *)(s_dev_list[INDEX_SPI].vir_base + pgoffset) = val;
2495  	#else
2496  	// for digit team
2497  	*(volatile uint32_t *)(s_dev_list[INDEX_SPI].phy_addr + pgoffset) = val;
2498  	#endif
2499  }
2500  
2501  int Xil_SPI_In32(uint32_t phyaddr)
2502  {
2503  	uint32_t val;
2504  	uint32_t pgoffset = phyaddr & ((uint32_t)(s_dev_list[INDEX_SPI].mem_size -1));
2505  
2506  	#ifdef SYSTEM_LINUX
2507  	// for software team
2508  	val = *(volatile uint32_t *)(s_dev_list[INDEX_SPI].vir_base + pgoffset);
2509  	#else
2510  	// for digit team
2511  	val = *(volatile uint32_t *)(s_dev_list[INDEX_SPI].phy_addr + pgoffset);
2512  	#endif
2513  
2514  	return val;
2515  }
2516  
2517  
2518  void set_led(uint8_t spi_id, uint32_t mode, uint32_t led_delay)
2519  {
2520  	uint32_t reg_val;
2521  
2522  	if (mode == LED_ON){
2523  		reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET);
2524  		Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET,(reg_val & (0xffffffff ^ ( 1 << spi_id)) ) | ((LED_ON & 0x1) << spi_id));
2525  	}
2526  	else if (mode == LED_OFF){
2527  		reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET);
2528  		Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET,(reg_val & (0xffffffff ^ ( 1 << spi_id)) ) | ((LED_OFF & 0x1) << spi_id));
2529  	}
2530  	else if (mode == LED_BLING_ON){
2531  		reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET);
2532  		Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET,(reg_val & (0xffffffff ^ ( 1 << spi_id)) ) | ((LED_OFF & 0x1) << spi_id));
2533  		cgsleep_us(led_delay*1000);
2534  		reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET);
2535  		Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET,(reg_val & (0xffffffff ^ ( 1 << spi_id)) ) | ((LED_ON & 0x1) << spi_id));
2536  		cgsleep_us(led_delay*1000);
2537  	}
2538  	else if (mode == LED_BLING_OFF){
2539  		reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET);
2540  		Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET,(reg_val & (0xffffffff ^ ( 1 << spi_id)) ) | ((LED_ON & 0x1) << spi_id));
2541  		cgsleep_us(led_delay*1000);
2542  		reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET);
2543  		Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET,(reg_val & (0xffffffff ^ ( 1 << spi_id)) ) | ((LED_OFF & 0x1) << spi_id));
2544  		cgsleep_us(led_delay*1000);
2545  	}
2546  }
2547  
2548  
2549  // ---------------------------------------------------------------------------
2550  // For check status
2551  // ---------------------------------------------------------------------------
2552  
2553  int clear_wait_st_idle(uint8_t spi_id, uint32_t timeout_us)
2554  {
2555  	uint32_t i;
2556  	uint32_t data_buf;
2557  	uint32_t cmd_status = 0;
2558  
2559  	for(i=0; i<timeout_us; i++){
2560  		cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2561  		if ((cmd_status&0xFF000000)==0x00000000) {
2562  			Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 0x00000800);
2563  			cgsleep_us(1);
2564  			Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 0x00000002);
2565  			Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 0x00000000);
2566  			data_buf = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2567  			if ((data_buf&0xFFFF00FF) != 0) {
2568  				applog(LOG_DEBUG, "clear_wait_st_idle SPI status is not cleared: %08x i=%0d ", data_buf&0xFFFF00FF, i);
2569  			}
2570  			break; // state=0 cmd_done=1
2571  		}
2572  		cgsleep_us(1);
2573  	}
2574  	if (i >= timeout_us){
2575  		applog(LOG_WARNING, "clear_wait_st_idle Wait SPI status clear timeout! i=%0d status=%8x ", i, cmd_status);
2576  		return XST_FAILURE;
2577  	}
2578  	else {
2579  		return XST_SUCCESS;
2580  	}
2581  }
2582  
2583  
2584  int wait_cmd_done(uint8_t spi_id, uint32_t timeout_us)
2585  {
2586  	uint32_t i;
2587  	uint32_t cmd_status = 0;
2588  	uint32_t timeout = timeout_us / 1000 + 1;
2589  
2590  	for(i = 0; i <= timeout; i++){ // polling cmd_done
2591  		cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2592  		applog(LOG_DEBUG, "Read SPI CMD_CTRL_REG2_ADDR: %08x ", cmd_status);
2593  		//getchar(); // for debug
2594  		if ((cmd_status&0xF0000000) != 0){ // spi fsm not idle
2595  		}
2596  		if ((cmd_status&0x00000001) == 1){
2597  			applog(LOG_DEBUG, "CMD  done, status: %08x! ", cmd_status);
2598  			break;
2599  		}
2600  		cgsleep_ms(1); //usleep(10);
2601  	}
2602  	if (i > timeout){
2603  		applog(LOG_WARNING, "SPI polling cmd done timeout! i=%0d ", i);
2604  		return XST_FAILURE;
2605  	}
2606  	else {
2607  		return XST_SUCCESS;
2608  	}
2609  }
2610  
2611  int wait_phy_idle(uint8_t spi_id, uint32_t timeout_us)
2612  {
2613  	uint32_t i;
2614  	uint32_t cmd_status = 0;
2615  	uint32_t timeout = timeout_us / 1000 + 1;
2616  
2617  	for(i = 0; i <= timeout; i++){
2618  		cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2619  		if ((cmd_status&0x00000040)==0x00000000) {
2620  			cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2621  			break; // state=0 cmd_done=1
2622  		}
2623  		cgsleep_ms(1); // usleep(1);
2624  	}
2625  	if (i >= timeout_us){
2626  		applog(LOG_WARNING, "Wait SPI status clear timeout! i=%0d status=%8x ", i, cmd_status);
2627  		return XST_FAILURE;
2628  	}
2629  	else {
2630  		return XST_SUCCESS;
2631  	}
2632  }
2633  
2634  int wait_spi_idle(uint8_t spi_id, uint32_t timeout_us)
2635  {
2636  	uint32_t i;
2637  	uint32_t cmd_status = 0;
2638  	uint32_t timeout = timeout_us / 1000 + 1;
2639  
2640  	for(i = 0; i <= timeout; i ++){
2641  		cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2642  		if ((cmd_status&0xFF000040)==0) return XST_SUCCESS;
2643  		cgsleep_ms(1); // usleep(20);
2644  	}
2645  
2646  	applog(LOG_DEBUG, "Wait SPI(%0d) idle timeout! time=%0d us, status=%8x ", spi_id, timeout_us, cmd_status);
2647  
2648  	return XST_FAILURE;
2649  }
2650  
2651  int wait_write_buf_empty(uint8_t spi_id, uint32_t timeout_us)
2652  {
2653  	uint32_t i;
2654  	uint32_t cmd_status = 0;
2655  	uint32_t timeout = timeout_us / 1000 + 1;
2656  
2657  	for(i = 0; i <= timeout; i++){
2658  		cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2659  		if ((cmd_status&0x03000000)==0) return XST_SUCCESS;
2660  		cgsleep_ms(1); // usleep(10); // polling interval
2661  	}
2662  
2663  	//printf("Wait command write queue empty timeout!spi=%0d i=%0d status=%8x ",spi_id, i, cmd_status);
2664  	return XST_FAILURE;
2665  }
2666  
2667  
2668  int check_cmd_status(uint8_t spi_id)
2669  {
2670  	uint32_t cmd_status = 0;
2671  
2672  	cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2673  	if (cmd_status & 0x00000004){
2674  		return XST_CRC_ERROR;
2675  	}
2676  
2677  	return XST_SUCCESS;
2678  }
2679  
2680  
2681  void reset_rx_buffer(uint8_t spi_id)
2682  {
2683  	uint32_t cmd_status = 0;
2684  	uint32_t write_data = 0;
2685  
2686  	cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG1_ADDR);
2687  	write_data = cmd_status & (~0x00000004);
2688  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG1_ADDR, write_data);
2689  	cgsleep_ms(1);
2690  	write_data = cmd_status | 0x00000004;
2691  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG1_ADDR, write_data);
2692  }
2693  
2694  // ---------------------------------------------------------------------------
2695  // Below function is for new SPI design's nonce/receive queue
2696  // ---------------------------------------------------------------------------
2697  void read_rx_buffer(uint8_t spi_id, uint8_t* buf8, uint32_t len_cfg)
2698  {
2699  	uint32_t i;
2700  	uint8_t rx_len;
2701  
2702  	rx_len = ((len_cfg & 0x0000FF00) >> 8)*2;
2703  
2704  	// Get nonce data
2705  	for(i = 0; i < rx_len; i+=4){
2706  		*(uint32_t*)(buf8+i) = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_READ_REG0_ADDR+i);
2707  	}
2708  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 0x00000800); // tell hw one nonce is fetched
2709  
2710  }
2711  
2712  
2713  void fill_tx_buffer(uint8_t spi_id, uint8_t* buf8, uint32_t byte_len)
2714  {
2715  	uint32_t i;
2716  
2717  	for(i = 0; i < byte_len; i+=4)
2718  	{
2719  		Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_WRITE_REG01_ADDR+i, *(uint32_t*)(buf8+i));
2720  	}
2721  }
2722  
2723  
2724  // ---------------------------------------------------------------------------
2725  // Below function is for new SPI design's send queue
2726  // ---------------------------------------------------------------------------
2727  
2728  // SPI bypass = 0
2729  int push_one_cmd(uint8_t spi_id, uint8_t* tx_buf8, uint32_t len_cfg, uint32_t last_job)
2730  {
2731  	//uint32_t i;
2732  	uint8_t  byte_len;
2733  	//uint32_t cmd_status;
2734  	uint16_t cmd_header;
2735  
2736  	byte_len = (len_cfg >> 24)*2;  // Not include ending zeros
2737  	cmd_header = (tx_buf8[1] << 8) | tx_buf8[0];
2738  
2739  	// wait command write queue empty
2740  	if (wait_write_buf_empty(spi_id, 10000) == XST_FAILURE) return XST_FAILURE;
2741  
2742  	if (wait_spi_idle(spi_id, 10000) == XST_FAILURE) return XST_FAILURE;
2743  
2744  	// write header to buffer
2745  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_WRITE_HEAD_ADDR, cmd_header);
2746  
2747  
2748  	// write data to buffer
2749  	fill_tx_buffer(spi_id, tx_buf8+2, byte_len-2); // Not include tx
2750  
2751  	// send command execution
2752  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG0_ADDR, len_cfg);
2753  	if (last_job)
2754  		Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 
2755  			0x00000001 | CHK_CMD | CHK_HY | CHK_LN);
2756  	else
2757  		Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 
2758  			0x00000011 | CHK_CMD | CHK_HY | CHK_LN);
2759  
2760  	return XST_SUCCESS;
2761  }
2762  
2763  /***************************************/
2764  //              interface
2765  /***************************************/
2766  
2767  
2768  void hub_spi_reset(uint8_t spi_id)
2769  {
2770  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG1_ADDR,0x00000010);
2771  	cgsleep_us(1);
2772  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG1_ADDR,0x0000001F);
2773  }
2774  
2775  int hub_spi_init(uint8_t spi_id, uint8_t chip_num)
2776  {
2777  	uint32_t Status;
2778  	//uint32_t i;
2779  
2780  	Status = Xil_SPI_In32(SPI_RESET_REG);
2781  
2782  	// reset
2783  	Xil_SPI_Out32(SPI_RESET_REG,(Status & ~(1 << spi_id)));
2784  	cgsleep_ms(1); // usleep(1);
2785  
2786  	Status = Xil_SPI_In32(SPI_RESET_REG);
2787  
2788  	// release reset
2789  	Xil_SPI_Out32(SPI_RESET_REG,(Status | (1 << spi_id)));
2790  
2791  	Status = Xil_SPI_In32(SPI_RESET_REG);
2792  
2793  	hub_spi_reset(spi_id);
2794  	// config max chip number
2795  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG0_ADDR,0x00041004|(chip_num<<24));
2796  	// config not check header
2797  //	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG3_ADDR,0x000F00FF);
2798  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG3_ADDR, 0x000F0000 & chip_num);
2799  	// config mask of each interrupt
2800  	Xil_SPI_Out32(MAIN_CFG_REG2_ADDR, 0x00000);
2801  
2802  	return XST_SUCCESS;
2803  }
2804  
2805  void hub_spi_clean_chain(uint32_t spi_id)
2806  {
2807  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH] = {0};
2808  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH] = {0};
2809  
2810  	spi_tx[0] = CMD_RESET;
2811  	spi_tx[1] = CMD_ADDR_BROADCAST;
2812  	spi_tx[2] = 0xff;
2813  	spi_tx[3] = 0xff;
2814  
2815  	do_spi_cmd(spi_id, spi_tx, spi_rx, 0x10001000);
2816  
2817  	hub_spi_reset(spi_id);
2818  }
2819  
2820  void hub_set_spi_speed(uint8_t spi_id, int select)
2821  {
2822  	uint32_t cfg[] =      {0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200100, 0x00330100};
2823  	//float mcu_spi_clk[] = {0.39062,    0.78125,    1.5625,     3.125,      6.25,       9.96};
2824  	uint32_t read_data;
2825  
2826  	read_data = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG0_ADDR);
2827  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG0_ADDR,(read_data&0xFF00FFFF)|cfg[select]);
2828  
2829  	read_data = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG0_ADDR);
2830  }
2831  
2832  
2833  // ----------- send job ------------
2834  int send_job_queue(uint8_t spi_id, uint8_t* tx_buf8, uint8_t __maybe_unused *rx_buf8, uint32_t len_cfg, uint32_t last_job)
2835  {
2836  	// push tx data to send buffer and start command
2837  	if (push_one_cmd(spi_id, tx_buf8, len_cfg, last_job) != XST_SUCCESS) return XST_FAILURE;
2838  
2839  	// wait all jobs are sent to chip
2840  	if (last_job){
2841  		if (wait_spi_idle(spi_id, 100000) == XST_FAILURE) return XST_FAILURE;
2842  	}
2843  
2844  	// Clear status. Not mandatory but suggest
2845  	if (last_job) clear_wait_st_idle(spi_id, 100000);
2846  
2847  	//  usleep(100);
2848  	return XST_SUCCESS;
2849  }
2850  
2851  
2852  int send_one_cmd_split(uint8_t spi_id, uint8_t* tx_buf8, uint32_t len_cfg, uint32_t last_job, uint8_t cs_low)
2853  {
2854  	uint32_t  byte_len;
2855  	uint16_t cmd_header;
2856  	uint32_t cfg_reg0;
2857  
2858  	byte_len = (len_cfg >> 24)*2;  // Not include ending zeros
2859  	cmd_header = (tx_buf8[1] << 8) | tx_buf8[0];
2860  
2861  	// change ext_zero to 0
2862  	cfg_reg0 = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG0_ADDR);
2863  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG0_ADDR,(cfg_reg0&0xFFFFFF00));
2864  
2865  
2866  	// wait command write queue empty
2867  	if (wait_write_buf_empty(spi_id, 10000) == XST_FAILURE) return XST_FAILURE;
2868  
2869  
2870  	// write header to buffer
2871  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_WRITE_HEAD_ADDR, cmd_header);
2872  
2873  
2874  	// write data to buffer
2875  	fill_tx_buffer(spi_id, tx_buf8+2, byte_len-2); // Not include tx
2876  
2877  
2878  	// send command execution
2879  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG0_ADDR, len_cfg);
2880  	if (last_job)
2881  		Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, (0x00000001 | CHK_HY | CHK_LN | cs_low<<14) );
2882  	else
2883  		Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, (0x00000011 | CHK_HY | CHK_LN | cs_low<<14) );
2884  
2885  
2886  	//    // check send queue full
2887  	//    cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2888  	//    if ((cmd_status&0x02000000)==0) {
2889  	//        DBGERROR("After push one command, send queue is not full!");
2890  	//        return XST_FAILURE;
2891  	//    }
2892  
2893  	// For half command application, can not use queue
2894  	wait_cmd_done(spi_id, 10000);
2895  
2896  
2897  	// change back ext_zero
2898  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG0_ADDR,cfg_reg0);
2899  
2900  
2901  	return XST_SUCCESS;
2902  
2903  }
2904  
2905  
2906  bool rece_queue_ready_check(uint8_t spi_id, uint32_t len, uint32_t timeout_us)
2907  {
2908  	uint32_t i;
2909  	uint32_t cmd_status;
2910  	uint32_t timeout = timeout_us / 1000 + 1;
2911  
2912  	for(i = 0; i <= timeout; i++){
2913  		cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2914  		if (((cmd_status&0x00000010)==0x00000010) && ((((cmd_status&0x0000FF00)>>8)>=(len)))) return true; // wait nonce_ready = 1, cmd_done = 1
2915  		//        if (((spi_tr.cmd_status&0x0000FF00)>>8)>=(len)) return true;
2916  		//        if ((spi_tr.cmd_status&0x00000010)==0x00000010) return true;
2917  		cgsleep_ms(1); // usleep(10);
2918  	}
2919  
2920  	return false;
2921  }
2922  
2923  // Check receive queue empty. true: empty
2924  bool rece_queue_empty_check(uint8_t spi_id, uint32_t timeout_us)
2925  {
2926  	uint32_t i;
2927  	uint32_t cmd_status;
2928  	uint32_t timeout = timeout_us / 1000 + 1;
2929  
2930  	for(i = 0; i <= timeout; i++){
2931  		cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2932  		if ((cmd_status & 0x0000ff10)==0x00000000) {
2933  			return true; // wait nonce_ready = 0, cmd_done = 1
2934  		}
2935  		cgsleep_ms(1); // usleep(10);
2936  	}
2937  
2938  	return false;
2939  }
2940  
2941  bool rece_queue_has_nonce(uint8_t spi_id, uint32_t __maybe_unused timeout_us)
2942  {
2943  	//uint32_t i;
2944  	uint32_t cmd_status;
2945  
2946  	cmd_status = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG2_ADDR);
2947  	if ( ((cmd_status&0x0000ff00) >= 0x00000600) && ((cmd_status&0x00000010) == 0x00000010) ) {
2948  		return true; // wait nonce_ready = 0, cmd_done = 1
2949  	}
2950  
2951  	return false;
2952  }
2953  
2954  
2955  void read_nonce_buffer(uint8_t spi_id, uint8_t* buf8, uint32_t len_cfg)
2956  {
2957  	uint32_t i;
2958  	uint8_t rx_len;
2959  
2960  	rx_len = (len_cfg & 0x0000FF00) >> 8;
2961  
2962  	// Get nonce data
2963  	for(i = 0; i < rx_len*2; i+=4){
2964  		*(uint32_t*)(buf8+i) = Xil_SPI_In32(SPI_BASEADDR_GAP*spi_id+CMD_READ_REG0_ADDR+i);
2965  	}
2966  	/*
2967  	 * if (buf8[0] == 00)
2968  	 * {
2969  	 * dump_spi_last_tr(spi_id);
2970  	}
2971  	*/
2972  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 0x00000B00); // tell hw one nonce is fetched, keep auto get nonce enable
2973  	cgsleep_ms(1); // usleep(1);
2974  }
2975  
2976  
2977  int pop_one_rece(uint8_t spi_id, uint8_t* rx_buf8, uint32_t len_cfg)
2978  {
2979  	//uint32_t i;
2980  	uint32_t len = (len_cfg & 0x0000ff00) >> 8;
2981  
2982  	// wait receive queue ready
2983  	if (rece_queue_ready_check(spi_id, len, 50000) == false) {
2984  		applog(LOG_INFO, "chain%d check receive buffer ready timeout!", spi_id);
2985  		return XST_FAILURE;
2986  	}
2987  	/*
2988  	 * if (check_crc_status(spi_id) != XST_SUCCESS) {
2989  	 * applog(LOG_WARNING, "crc error ");
2990  	 * return XST_CRC_ERROR;
2991  	 * }
2992  	 */
2993  	// read back rx data
2994  	read_rx_buffer(spi_id, rx_buf8, len_cfg);
2995  
2996  	return XST_SUCCESS;
2997  }
2998  
2999  
3000  int do_spi_cmd(uint8_t spi_id, uint8_t* tx_buf8, uint8_t* rx_buf8, uint32_t len_cfg)
3001  {
3002  	// reset_rx_buffer(spi_id);
3003  
3004  	// push tx data to send buffer and start command
3005  	if (push_one_cmd(spi_id, tx_buf8, len_cfg, 1) != XST_SUCCESS) {
3006  		applog(LOG_ERR, "ERROR - failed to send spi cmd");
3007  		return XST_FAILURE;
3008  	}
3009  
3010  	// read back rx data
3011  	if (pop_one_rece(spi_id, rx_buf8, len_cfg) != XST_SUCCESS) {
3012  		applog(LOG_ERR, "ERROR - failed to recv spi data");
3013  		return XST_FAILURE;
3014  	}
3015  
3016  	if ((tx_buf8[0] & 0x0f) != (rx_buf8[0] & 0x0f)) {
3017  		//hexdump_error("ERROR - recvbuf:", rx_buf8, 16);
3018  		return XST_FAILURE;
3019  	}
3020  
3021  	// Clear status. Not mandatory but suggest
3022  	clear_wait_st_idle(spi_id, 200);
3023  
3024  	return XST_SUCCESS;
3025  }
3026  
3027  
3028  void enable_auto_cmd0a(uint8_t spi_id, uint32_t threshold, uint32_t msb, uint32_t lsb, uint32_t large_en, uint32_t mode )//mode : 1 only cmd0a;0 cmd08 follows cmd0a
3029  {
3030  	uint32_t val;
3031  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 0x00000000 | CHK_CMD);
3032  	val = ((msb << 24) & 0xff000000) | ((lsb << 16) & 0xff0000) | ((mode & 0x1) << 14) | ((large_en & 0x1) << 13) | (0x1 << 12) | ( threshold & 0xfff );
3033  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+AUTO_CMD0A_REG0_ADDR, val);
3034  }
3035  
3036  void disable_auto_cmd0a(uint8_t spi_id, uint32_t threshold, uint32_t msb, uint32_t lsb, uint32_t large_en, uint32_t mode )//mode : 1 only cmd0a;0 cmd08 follows cmd0a
3037  {
3038  	uint32_t val;
3039  	val = ((msb << 24) & 0xff000000) | ((lsb << 16) & 0xff0000) | ((mode & 0x1) << 14) | ((large_en & 0x1) << 13) | (0x0 << 12) | ( threshold & 0xfff );
3040  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+AUTO_CMD0A_REG0_ADDR, val);
3041  }
3042  
3043  
3044  int enable_auto_nonce(uint8_t spi_id, uint16_t cmd08_cmd, uint32_t len_cfg)
3045  {
3046  	uint8_t send_buf8[12] = {0};
3047  
3048  	// wait all previous command done
3049  	//clear_wait_st_idle(spi_id, 1000000);
3050  	wait_spi_idle(spi_id, 10000);
3051  
3052  	// set auto get nonce
3053  	//for(i=0; i<spi_tr.tx_len; i++){spi_tr.tx_buf[i] = 0;} // clear tx_buf variable for debug print
3054  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_WRITE_HEAD_ADDR, REORDER16(cmd08_cmd));
3055  	fill_tx_buffer(spi_id, send_buf8, 10);
3056  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+MAIN_CFG_REG3_ADDR, 0x000000ff); // auto cmd08 gap
3057  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG0_ADDR, len_cfg);
3058  	//Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 0x00000002); // clear status
3059  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 0x00000300 | CHK_CMD); // cmd08 do
3060  
3061  	return XST_SUCCESS;
3062  }
3063  
3064  int disable_auto_nonce(uint8_t spi_id)
3065  {
3066  	Xil_SPI_Out32(SPI_BASEADDR_GAP*spi_id+CMD_CTRL_REG1_ADDR, 0x00000000); // disable auto get nonce
3067  
3068  	// wait command done
3069  	return (clear_wait_st_idle(spi_id, 1000000));
3070  
3071  }
3072  
3073  // 3.3v GPIO output
3074  void hub_set_power_en(uint8_t chain_id, int value)
3075  {
3076  	uint32_t reg_val;
3077  
3078  	if (misc_get_vid_type() == MCOMPAT_LIB_VID_I2C_TYPE) {
3079  		hub_set_power_en_i2c(chain_id, value);
3080  		sleep(3);
3081  	}
3082  
3083  	reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG8_OFFSET);
3084  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG8_OFFSET, (reg_val & (~(0x1 << (18 + chain_id)))) | ((value & 0x1) << (18 + chain_id)));
3085  	//reg_val = Xil_In32(XPAR_VID_LED_BUZZER_CTRL_0_S00_AXI_BASEADDR + VID_LED_BUZZER_CTRL_S00_AXI_SLV_REG0_OFFSET + chain_id*4);
3086  	//Xil_Peripheral_Out32(XPAR_VID_LED_BUZZER_CTRL_0_S00_AXI_BASEADDR + VID_LED_BUZZER_CTRL_S00_AXI_SLV_REG0_OFFSET + chain_id*4, (reg_val & 0xfffeffff) | ((value & 0x1) << 16));
3087  }
3088  
3089  // 1.8v GPIO output
3090  void hub_set_start_en(uint8_t chain_id, int value)
3091  {
3092  	uint32_t reg_val;
3093  
3094  	reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG8_OFFSET);
3095  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG8_OFFSET, (reg_val & (~(0x1 << chain_id))) | ((value & 0x1) << chain_id));
3096  	//reg_val = Xil_In32(XPAR_VID_LED_BUZZER_CTRL_0_S00_AXI_BASEADDR + VID_LED_BUZZER_CTRL_S00_AXI_SLV_REG0_OFFSET + chain_id*4);
3097  	//Xil_Peripheral_Out32(XPAR_VID_LED_BUZZER_CTRL_0_S00_AXI_BASEADDR + VID_LED_BUZZER_CTRL_S00_AXI_SLV_REG0_OFFSET + chain_id*4, (reg_val & 0xfffbffff) | ((value & 0x1) << 18));
3098  }
3099  
3100  // 1.8v GPIO output
3101  bool hub_set_reset(uint8_t chain_id, int value)
3102  {
3103  	uint32_t reg_val;
3104  
3105  	reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG8_OFFSET);
3106  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG8_OFFSET, (reg_val & (~(0x1 << (9 + chain_id)))) | ((value & 0x1) << (9 + chain_id)));
3107  	//reg_val = Xil_Peripheral_In32(XPAR_VID_LED_BUZZER_CTRL_0_S00_AXI_BASEADDR + VID_LED_BUZZER_CTRL_S00_AXI_SLV_REG0_OFFSET + chain_id*4);
3108  	//Xil_Peripheral_Out32(XPAR_VID_LED_BUZZER_CTRL_0_S00_AXI_BASEADDR + VID_LED_BUZZER_CTRL_S00_AXI_SLV_REG0_OFFSET + chain_id*4, (reg_val & 0xfffdffff) | ((value & 0x1) << 17));
3109  	return true;
3110  }
3111  
3112  void hub_set_led(uint8_t chain_id, int mode)
3113  {
3114  	uint32_t reg_val;
3115  
3116  	if (mode == LED_ON){
3117  		reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET);
3118  		Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET,(reg_val & (0xffffffff ^ ( 1 << chain_id)) ) | ((LED_ON & 0x1) << chain_id));
3119  	}
3120  	else if (mode == LED_OFF){
3121  		reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET);
3122  		Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET,(reg_val & (0xffffffff ^ ( 1 << chain_id)) ) | ((LED_OFF & 0x1) << chain_id));
3123  	}
3124  }
3125  
3126  int hub_get_plug(uint8_t chain_id)
3127  {
3128  	uint32_t reg_val;
3129  
3130  	reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG10_OFFSET);
3131  	return ((reg_val >> chain_id) & 0x01);
3132  }
3133  
3134  
3135  #ifdef SYSTEM_LINUX
3136  static int set_warn(int spi_id)
3137  {
3138  	mcompat_set_power_en(spi_id, 0);
3139  	sleep(1);
3140  	mcompat_set_reset(spi_id, 0);
3141  	mcompat_set_start_en(spi_id, 0);
3142  
3143  	do
3144  	{
3145  		mcompat_set_led(spi_id, 1);
3146  		sleep(1);
3147  		mcompat_set_led(spi_id, 0);
3148  		sleep(1);
3149  	}while(1);
3150  
3151  	return 0;
3152  }
3153  
3154  
3155  static void hub_get_hitemp_stat(uint8_t chain_id,mcompat_temp_s *temp_ctrl)
3156  {
3157  	bool over_temp = false;
3158  	int reg_val;
3159  	int tmp_val;
3160  
3161  	reg_val = Xil_SPI_In32(SPI_BASEADDR_GAP*chain_id+AUTO_CMD0A_REG3_ADDR);
3162  
3163  	tmp_val = ((reg_val ) & 0x3ff) < g_temp_hi_thr ? 0x0:((reg_val) & 0x3ff);
3164  	tmp_val = tmp_val > g_temp_lo_thr ? 0x0:tmp_val;
3165  	temp_ctrl->temp_highest[0] = tmp_val;
3166  
3167  	if ((temp_ctrl->temp_highest[0]) &&(temp_ctrl->temp_highest[0] < g_dangerous_temp))
3168  		over_temp = true;
3169  
3170  	tmp_val = ((reg_val >> 10) & 0x3ff) < g_temp_hi_thr ? 0x0:((reg_val >> 10) & 0x3ff);
3171  	tmp_val = tmp_val > g_temp_lo_thr ? 0x0:tmp_val;
3172  	temp_ctrl->temp_highest[1] = tmp_val;
3173  
3174  	if ((temp_ctrl->temp_highest[1]) &&(temp_ctrl->temp_highest[1] < g_dangerous_temp))
3175  		over_temp = true;
3176  
3177  	tmp_val = ((reg_val >> 20) & 0x3ff) < g_temp_hi_thr ? 0x0:((reg_val >> 20) & 0x3ff);
3178  	tmp_val = tmp_val > g_temp_lo_thr ? 0x0:tmp_val;
3179  	temp_ctrl->temp_highest[2] = (reg_val >> 20 ) & 0x3ff;
3180  
3181  	if ((temp_ctrl->temp_highest[2]) &&(temp_ctrl->temp_highest[2] < g_dangerous_temp))
3182  		over_temp = true;
3183  
3184  	if (over_temp == true)
3185  		set_warn(chain_id);
3186  
3187  	applog(LOG_INFO,"chain %d,Hi: %d,%d,%d",chain_id,temp_ctrl->temp_highest[0],temp_ctrl->temp_highest[1],temp_ctrl->temp_highest[2]);
3188  }
3189  
3190  static void hub_get_lotemp_stat(uint8_t chain_id,mcompat_temp_s *temp_ctrl)
3191  {
3192  	int reg_val;
3193  	int tmp_val;
3194  
3195  	reg_val =  Xil_SPI_In32(SPI_BASEADDR_GAP*chain_id+AUTO_CMD0A_REG2_ADDR);
3196  
3197  
3198  	tmp_val = ((reg_val) & 0x3ff) < g_temp_hi_thr ? 0x0:((reg_val) & 0x3ff);
3199  	tmp_val = tmp_val > g_temp_lo_thr ? 0x0:tmp_val;
3200  	temp_ctrl->temp_lowest[0] = tmp_val;
3201  
3202  	tmp_val = ((reg_val >> 10) & 0x3ff) < g_temp_hi_thr ? 0x0:((reg_val >> 10) & 0x3ff);
3203  	tmp_val = tmp_val > g_temp_lo_thr ? 0x0:tmp_val;
3204  	temp_ctrl->temp_lowest[1] = tmp_val;
3205  
3206  
3207  	tmp_val = ((reg_val >> 20) & 0x3ff) < g_temp_hi_thr ? 0x0:((reg_val >> 20) & 0x3ff);
3208  	tmp_val = tmp_val > g_temp_lo_thr ? 0x0:tmp_val;
3209  	temp_ctrl->temp_lowest[2] = tmp_val;
3210  	applog(LOG_INFO,"chain %d,lo: %d,%d,%d",chain_id,temp_ctrl->temp_lowest[0],temp_ctrl->temp_lowest[1],temp_ctrl->temp_lowest[2]);
3211  }
3212  
3213  static void hub_get_avgtemp_stat(uint8_t chain_id,mcompat_temp_s *temp_ctrl)
3214  {
3215  	int reg_val;
3216  	int tmp_val;
3217  
3218  	reg_val =  Xil_SPI_In32(SPI_BASEADDR_GAP*chain_id+AUTO_CMD0A_REG4_ADDR);
3219  
3220  	tmp_val = 2 * ((reg_val ) & 0xffff) / g_chip_num;
3221  
3222  
3223  	tmp_val = tmp_val < g_temp_hi_thr ? 0x0:tmp_val;
3224  	tmp_val = tmp_val > g_temp_lo_thr ? 0x0:tmp_val;
3225  	temp_ctrl->final_temp_avg = tmp_val;
3226  	applog(LOG_INFO,"chain %d,avg: %d",chain_id,temp_ctrl->final_temp_avg);
3227  }
3228  #endif
3229  
3230  
3231  void hub_set_vid_vid(uint8_t chain_id, int vid)
3232  {
3233  	uint32_t reg_val = 0;
3234  	int i = 0;
3235  	uint8_t vid_binary[16] = {0};
3236  
3237  	for(i = 0; i < 8; i ++)
3238  	{
3239  		vid_binary[i] = ((vid >> i) & 0x1) ? 7 : 1;
3240  		vid_binary[8+i] = (vid_binary[i] == 1) ? 7 : 1;
3241  	}
3242  
3243  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG32_OFFSET, 25000);
3244  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG33_OFFSET, (vid_binary[3] << 28) | (vid_binary[2] << 24) | (vid_binary[1] << 20) | (vid_binary[0] << 16) | 0xff);
3245  	reg_val = 0;
3246  	for(i = 0; i < 8; i ++)
3247  	{
3248  		reg_val = (vid_binary[i+4] << (i*4)) | reg_val;
3249  	}
3250  
3251  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG34_OFFSET, reg_val);
3252  	reg_val = 0;
3253  	for(i = 0; i < 4; i ++)
3254  	{
3255  		reg_val = (vid_binary[i+12] << (i*4)) | reg_val;
3256  	}
3257  
3258  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG35_OFFSET, reg_val);
3259  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG39_OFFSET, 80 | (4 << 16));
3260  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG4_OFFSET, 0x1 << chain_id);
3261  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG3_OFFSET, 0x1 );
3262  
3263  	cgsleep_ms(100);
3264  }
3265  
3266  void hub_set_vid_uart_select(uint8_t spi_id)
3267  {
3268  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG4_OFFSET, (0x1 << 16) | (0x1 << spi_id));
3269  }
3270  
3271  void hub_set_pwm(uint8_t fan_id, int frequency, int duty)
3272  {
3273  	#if 0
3274  	int duty_driver = 0;
3275  	unsigned int value;
3276  	duty_driver = frequency / 100 * duty;
3277  
3278  	value = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG16_OFFSET + fan_id*8);
3279  	value = value | (1<<fan_id);
3280  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG2_OFFSET, value);
3281  
3282  	//Xil_Fans_Out32(XPAR_FANS_CTRL_0_S00_AXI_BASEADDR + FANS_CTRL_S00_AXI_SLV_REG1_OFFSET + fan_id*8, frequency);
3283  	//Xil_Fans_Out32(XPAR_FANS_CTRL_0_S00_AXI_BASEADDR + FANS_CTRL_S00_AXI_SLV_REG0_OFFSET + fan_id*8, duty_driver | (0x1 << 31));
3284  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG16_OFFSET + fan_id*8, frequency);
3285  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG17_OFFSET + fan_id*8, duty_driver | (0x1 << 31));
3286  	#else
3287  	int duty_driver = 0;
3288  	uint32_t reg_val;
3289  	duty_driver = frequency / 100 * duty;
3290  
3291  	applog(LOG_DEBUG, "%s,%d: fan_id %d, freq: %d duty: %d.", __FILE__, __LINE__, fan_id, frequency, duty);
3292  
3293  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG16_OFFSET + fan_id*8, frequency);
3294  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG17_OFFSET + fan_id*8, duty_driver);
3295  	reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG2_OFFSET);
3296  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG2_OFFSET, (reg_val & (~(0x1 << fan_id))) | (0x1 << fan_id));
3297  	#endif
3298  }
3299  
3300  int hub_get_button(void)
3301  {
3302  	uint32_t reg_val;
3303  
3304  	reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG10_OFFSET);
3305  	return (((reg_val >> 16) & 0x1));
3306  }
3307  
3308  void hub_set_green_led(int mode)
3309  {
3310  	uint32_t reg_val,SetRedRegValue;
3311  	reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET);
3312  
3313  	if (LED_ON == mode)
3314  	{
3315  		SetRedRegValue = reg_val | 0x200;
3316  	}
3317  	else
3318  	{
3319  		SetRedRegValue = reg_val & (~0x200);
3320  	}
3321  
3322  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET,SetRedRegValue);
3323  }
3324  
3325  void hub_set_red_led(int mode)
3326  {
3327  	uint32_t reg_val,SetRedRegValue;
3328  	reg_val = Xil_Peripheral_In32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET);
3329  
3330  	if (LED_ON == mode)
3331  	{
3332  		SetRedRegValue = reg_val | 0x400;
3333  	}
3334  	else
3335  	{
3336  		SetRedRegValue = reg_val & (~0x400);
3337  	}
3338  
3339  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG9_OFFSET,SetRedRegValue);
3340  }
3341  
3342  void init_hub_gpio(void)
3343  {
3344  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG1_OFFSET, 0);
3345  	sleep(1);
3346  	Xil_Peripheral_Out32(MCOMPAT_PERIPHERAL_S00_AXI_SLV_REG1_OFFSET, 3);
3347  }
3348  
3349  void flush_spi(uint8_t chain_id)
3350  {
3351  	uint16_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3352  	uint16_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3353  
3354  	memset(spi_tx, 0, sizeof(spi_tx));
3355  	memset(spi_rx, 0, sizeof(spi_rx));
3356  
3357  	opi_spi_transfer(chain_id, spi_tx, spi_rx, MCOMPAT_CONFIG_MAX_CMD_LENGTH);
3358  }
3359  
3360  bool opi_spi_read_write(uint8_t chain_id, uint8_t *txbuf, uint8_t *rxbuf, int len)
3361  {
3362  	int i;
3363  	bool ret;
3364  	int len16 = len / 2;
3365  	uint16_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3366  	uint16_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3367  
3368  	if (rxbuf == NULL)
3369  	{
3370  		applog(LOG_ERR, "%s,%s() %d: para erro! ", __FILE__, __func__, __LINE__);
3371  	}
3372  
3373  	memset(spi_tx, 0, sizeof(spi_tx));
3374  	memset(spi_rx, 0, sizeof(spi_rx));
3375  
3376  	if (txbuf == NULL)
3377  	{
3378  		ret = opi_spi_transfer(chain_id, NULL, spi_rx, len16);
3379  	}
3380  	else
3381  	{
3382  		for(i = 0; i < len16; i++)
3383  		{
3384  			spi_tx[i] = OPI_MAKE_WORD(txbuf[2*i], txbuf[(2*i)+1]);
3385  		}
3386  
3387  		ret = opi_spi_transfer(chain_id, spi_tx, spi_rx, len16);
3388  	}
3389  
3390  	if (!ret)
3391  	{
3392  		return false;
3393  	}
3394  
3395  	for(i = 0; i < len16; i++)
3396  	{
3397  		rxbuf[2*i]		= OPI_HI_BYTE(spi_rx[i]);
3398  		rxbuf[(2*i)+1]	= OPI_LO_BYTE(spi_rx[i]);
3399  	}
3400  
3401  	return true;
3402  }
3403  
3404  
3405  bool opi_send_command(uint8_t chain_id, uint8_t cmd, uint8_t chip_id, uint8_t *buff, int len)
3406  {
3407  	int tx_len;
3408  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3409  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3410  
3411  	if (buff == NULL)
3412  	{
3413  		applog(LOG_ERR, "%s,%s() %d: para erro! ", __FILE__, __func__, __LINE__);
3414  	}
3415  
3416  	memset(spi_tx, 0, sizeof(spi_tx));
3417  	memset(spi_rx, 0, sizeof(spi_rx));
3418  
3419  	spi_tx[0] = OPI_HI_BYTE(AX_CMD_SYNC_HEAD);
3420  	spi_tx[1] = OPI_LO_BYTE(AX_CMD_SYNC_HEAD);
3421  
3422  	spi_tx[2] = cmd;
3423  	spi_tx[3] = chip_id;
3424  
3425  	if (len > 0)
3426  	{
3427  		memcpy(spi_tx + 4, buff, len);
3428  	}
3429  
3430  	tx_len = (4 + len + 1) & ~1;
3431  
3432  	if (opi_spi_read_write(chain_id, spi_tx, spi_rx, tx_len))
3433  	{
3434  		return true;
3435  	}
3436  	else
3437  	{
3438  		applog(LOG_ERR, "send command fail !");
3439  		return false;
3440  	}
3441  }
3442  
3443  
3444  bool opi_poll_result(uint8_t chain_id, uint8_t cmd, uint8_t __maybe_unused chip_id, uint8_t *buff, int len)
3445  {
3446  	int i;
3447  	int tx_len;
3448  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3449  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3450  
3451  	if (buff == NULL)
3452  	{
3453  		applog(LOG_ERR, "%s,%s() %d: para erro! ", __FILE__, __func__, __LINE__);
3454  	}
3455  
3456  	memset(spi_tx, 0, sizeof(spi_tx));
3457  	memset(spi_rx, 0, sizeof(spi_rx));
3458  
3459  	tx_len = g_chip_num * 4;
3460  
3461  	for(i = 0; i < tx_len; i++) {
3462  		cgsleep_ms(1); // usleep(1);
3463  
3464  		if (opi_spi_read_write(chain_id, NULL, spi_rx, 2))
3465  		{
3466  			break;
3467  		}
3468  	}
3469  
3470  	if (i >= tx_len)
3471  	{
3472  		applog(LOG_ERR, "%s,%d: poll fail !", __FILE__, __LINE__);
3473  		return false;
3474  	}
3475  
3476  	if ((spi_rx[0] != OPI_HI_BYTE(AX_CMD_SYNC_HEAD)) || (spi_rx[1] != OPI_LO_BYTE(AX_CMD_SYNC_HEAD)))
3477  	{
3478  		return false;
3479  	}
3480  
3481  	opi_spi_read_write(chain_id, NULL, spi_rx, 2);
3482  	if (spi_rx[1] != OPI_STATUS_SUC)
3483  	{
3484  		return false;
3485  	}
3486  
3487  	opi_spi_read_write(chain_id, NULL, spi_rx, 2);
3488  	if ((spi_rx[0] & 0x0f) != cmd)
3489  	{
3490  		return false;
3491  	}
3492  
3493  	if (len > 0)
3494  	{
3495  		opi_spi_read_write(chain_id, NULL, spi_rx+2, len);
3496  	}
3497  
3498  	memcpy(buff, spi_rx, len+2);
3499  
3500  	return true;
3501  }
3502  
3503  
3504  
3505  bool opi_send_cmd(uint8_t chain_id, uint8_t cmd, uint8_t *buff, int len)
3506  {
3507  	int tx_len;
3508  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3509  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3510  
3511  	if ((buff == NULL) && (len != 0))
3512  	{
3513  		applog(LOG_ERR, "%s,%s() %d: para erro! ", __FILE__, __func__, __LINE__);
3514  	}
3515  
3516  	memset(spi_tx, 0, sizeof(spi_tx));
3517  	memset(spi_rx, 0, sizeof(spi_rx));
3518  
3519  	spi_tx[0] = OPI_HI_BYTE(CUSTOM_SYNC_HEAD);
3520  	spi_tx[1] = OPI_LO_BYTE(CUSTOM_SYNC_HEAD);
3521  
3522  	spi_tx[2] = cmd;
3523  	spi_tx[3] = 0;
3524  
3525  	if (len > 0)
3526  	{
3527  		memcpy(spi_tx + 4, buff, len);
3528  	}
3529  
3530  	tx_len = (4 + len + 1) & ~1;
3531  
3532  	if (opi_spi_read_write(chain_id, spi_tx, spi_rx, tx_len))
3533  	{
3534  		return true;
3535  	}
3536  	else
3537  	{
3538  		applog(LOG_ERR, "send command fail !");
3539  		return false;
3540  	}
3541  }
3542  
3543  
3544  bool opi_poll_rslt(uint8_t chain_id, uint8_t __maybe_unused cmd, uint8_t *buff, int len)
3545  {
3546  	int i;
3547  	int tx_len;
3548  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3549  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3550  
3551  	if ((buff == NULL) && (len != 0))
3552  	{
3553  		applog(LOG_ERR, "%s,%s() %d: para erro! ", __FILE__, __func__, __LINE__);
3554  	}
3555  
3556  	memset(spi_tx, 0, sizeof(spi_tx));
3557  	memset(spi_rx, 0, sizeof(spi_rx));
3558  
3559  	tx_len = g_chip_num * 4;
3560  
3561  	for(i = 0; i < tx_len; i++) {
3562  		cgsleep_ms(1); // usleep(1);
3563  
3564  		if (opi_spi_read_write(chain_id, NULL, spi_rx, 2))
3565  		{
3566  			break;
3567  		}
3568  	}
3569  
3570  	if (i >= tx_len)
3571  	{
3572  		applog(LOG_ERR, "%s,%d: poll fail !", __FILE__, __LINE__);
3573  		return false;
3574  	}
3575  
3576  	if ((spi_rx[0] != OPI_HI_BYTE(CUSTOM_SYNC_HEAD)) || (spi_rx[1] != OPI_LO_BYTE(CUSTOM_SYNC_HEAD)))
3577  	{
3578  		return false;
3579  	}
3580  
3581  	opi_spi_read_write(chain_id, NULL, spi_rx, 2);
3582  	if (spi_rx[1] != OPI_STATUS_SUC)
3583  	{
3584  		return false;
3585  	}
3586  
3587  	if (len > 0)
3588  	{
3589  		opi_spi_read_write(chain_id, NULL, spi_rx+2, len);
3590  		memcpy(buff, spi_rx+2, len);
3591  	}
3592  
3593  	return true;
3594  }
3595  
3596  
3597  void opi_set_power_en(unsigned char chain_id, int val)
3598  {
3599  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3600  
3601  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3602  
3603  	tx_buf[0] = (val >> 0) & 0xff;
3604  	tx_buf[1] = (val >> 8) & 0xff;
3605  
3606  	if (!opi_send_cmd(chain_id, OPI_SET_POWER_EN, tx_buf, 2))
3607  	{
3608  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3609  		return;
3610  	}
3611  
3612  	if (!opi_poll_rslt(chain_id, OPI_SET_POWER_EN, NULL, 0))
3613  	{
3614  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3615  		return;
3616  	}
3617  }
3618  
3619  
3620  void opi_set_start_en(unsigned char chain_id, int val)
3621  {
3622  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3623  
3624  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3625  
3626  	tx_buf[0] = (val >> 0) & 0xff;
3627  	tx_buf[1] = (val >> 8) & 0xff;
3628  
3629  	if (!opi_send_cmd(chain_id, OPI_SET_STARR_EN, tx_buf, 2))
3630  	{
3631  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3632  		return;
3633  	}
3634  
3635  	if (!opi_poll_rslt(chain_id, OPI_SET_STARR_EN, NULL, 0))
3636  	{
3637  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3638  		return;
3639  	}
3640  }
3641  
3642  
3643  bool opi_set_reset(unsigned char chain_id, int val)
3644  {
3645  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3646  
3647  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3648  
3649  	tx_buf[0] = (val >> 0) & 0xff;
3650  	tx_buf[1] = (val >> 8) & 0xff;
3651  
3652  	if (!opi_send_cmd(chain_id, OPI_SET_RESET, tx_buf, 2)) {
3653  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3654  		return false;
3655  	}
3656  
3657  	if (!opi_poll_rslt(chain_id, OPI_SET_RESET, NULL, 0)) {
3658  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3659  		return false;
3660  	}
3661  	return true;
3662  }
3663  
3664  
3665  void opi_set_led(unsigned char chain_id, int val)
3666  {
3667  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3668  
3669  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3670  
3671  	tx_buf[0] = (val >> 0) & 0xff;
3672  	tx_buf[1] = (val >> 8) & 0xff;
3673  
3674  	if (!opi_send_cmd(chain_id, OPI_SET_LED, tx_buf, 2))
3675  	{
3676  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3677  		return;
3678  	}
3679  
3680  	if (!opi_poll_rslt(chain_id, OPI_SET_LED, NULL, 0))
3681  	{
3682  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3683  		return;
3684  	}
3685  }
3686  
3687  
3688  int opi_get_plug(unsigned char chain_id)
3689  {    
3690  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3691  
3692  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3693  
3694  	if (!opi_send_cmd(chain_id, OPI_SET_LED, NULL, 0))
3695  	{
3696  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3697  		return -1;
3698  	}
3699  
3700  	memset(rx_buf, 0, sizeof(rx_buf));
3701  	if (!opi_poll_rslt(chain_id, OPI_SET_LED, rx_buf, 2))
3702  	{
3703  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3704  		return -1;
3705  	}
3706  
3707  	return (int)(rx_buf[0]);
3708  }
3709  
3710  
3711  bool opi_set_vid(unsigned char chain_id, int vid)
3712  {
3713  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3714  
3715  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3716  
3717  	tx_buf[0] = (vid >> 0) & 0xff;
3718  	tx_buf[1] = (vid >> 8) & 0xff;
3719  
3720  	if (!opi_send_cmd(chain_id, OPI_SET_VID, tx_buf, 2))
3721  	{
3722  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3723  		return false;
3724  	}
3725  
3726  	if (!opi_poll_rslt(chain_id, OPI_SET_VID, NULL, 0))
3727  	{
3728  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3729  		return false;
3730  	}
3731  
3732  	return true;
3733  }
3734  
3735  
3736  void opi_set_pwm(unsigned char fan_id, int frequency, int duty)
3737  {
3738  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3739  
3740  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3741  
3742  	tx_buf[0] = fan_id;
3743  	tx_buf[1] = 0x00;
3744  
3745  	tx_buf[2] = (frequency >> 0) & 0xff;
3746  	tx_buf[3] = (frequency >> 8) & 0xff;
3747  	tx_buf[4] = (frequency >> 16) & 0xff;
3748  	tx_buf[5] = (frequency >> 24) & 0xff;
3749  
3750  	tx_buf[6] = (duty >> 0) & 0xff;
3751  	tx_buf[7] = (duty >> 8) & 0xff;
3752  
3753  	if (!opi_send_cmd(0, OPI_SET_PWM, tx_buf, 8))
3754  	{
3755  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3756  		return;
3757  	}
3758  
3759  	if (!opi_poll_rslt(0, OPI_SET_PWM, NULL, 0))
3760  	{
3761  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3762  		return;
3763  	}
3764  }
3765  
3766  bool opi_chain_power_on(unsigned char chain_id)
3767  {
3768  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3769  
3770  	if (!opi_send_cmd(chain_id, OPI_POWER_ON, NULL, 0))
3771  	{
3772  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3773  		return false;
3774  	}
3775  
3776  	if (!opi_poll_rslt(chain_id, OPI_POWER_ON, NULL, 0))
3777  	{
3778  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3779  		return false;
3780  	}
3781  
3782  	return true;
3783  }
3784  
3785  
3786  bool opi_chain_power_down(unsigned char chain_id)
3787  {
3788  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3789  
3790  	if (!opi_send_cmd(chain_id, OPI_POWER_DOWN, NULL, 0))
3791  	{
3792  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3793  		return false;
3794  	}
3795  
3796  	if (!opi_poll_rslt(chain_id, OPI_POWER_DOWN, NULL, 0))
3797  	{
3798  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3799  		return false;
3800  	}
3801  
3802  	return true;
3803  }
3804  
3805  bool opi_chain_hw_reset(unsigned char chain_id)
3806  {
3807  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3808  
3809  	if (!opi_send_cmd(chain_id, OPI_POWER_RESET, NULL, 0))
3810  	{
3811  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3812  		return false;
3813  	}
3814  
3815  	if (!opi_poll_rslt(chain_id, OPI_POWER_RESET, NULL, 0))
3816  	{
3817  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3818  		return false;
3819  	}
3820  
3821  	return true;
3822  }
3823  
3824  
3825  bool opi_chain_power_on_all(void)
3826  {
3827  	int i;
3828  
3829  	for(i = 0; i < g_chain_num; i++)
3830  	{
3831  		opi_chain_power_on(i);
3832  	}
3833  
3834  	return true;
3835  }
3836  
3837  bool opi_chain_power_down_all(void)
3838  {
3839  	int i;
3840  
3841  	for(i = 0; i < g_chain_num; i++)
3842  	{
3843  		opi_chain_power_down(i);
3844  	}
3845  
3846  	return true;
3847  }
3848  
3849  
3850  void opi_set_spi_speed(unsigned char chain_id, int index)
3851  {
3852  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3853  
3854  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
3855  
3856  	tx_buf[0] = (index >> 0) & 0xff;
3857  	tx_buf[1] = (index >> 8) & 0xff;
3858  
3859  	if (!opi_send_cmd(chain_id, OPI_SET_SPI_SPEED, tx_buf, 2))
3860  	{
3861  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
3862  		return;
3863  	}
3864  
3865  	if (!opi_poll_rslt(chain_id, OPI_SET_SPI_SPEED, NULL, 0))
3866  	{
3867  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
3868  		return;
3869  	}
3870  }
3871  
3872  const int pin_power_en[] =
3873  {
3874  	MCOMPAT_CONFIG_CHAIN0_POWER_EN_GPIO,
3875  	MCOMPAT_CONFIG_CHAIN1_POWER_EN_GPIO,
3876  	MCOMPAT_CONFIG_CHAIN2_POWER_EN_GPIO,
3877  	MCOMPAT_CONFIG_CHAIN3_POWER_EN_GPIO,
3878  	MCOMPAT_CONFIG_CHAIN4_POWER_EN_GPIO,
3879  	MCOMPAT_CONFIG_CHAIN5_POWER_EN_GPIO,
3880  	MCOMPAT_CONFIG_CHAIN6_POWER_EN_GPIO,
3881  	MCOMPAT_CONFIG_CHAIN7_POWER_EN_GPIO
3882  };
3883  
3884  const int pin_start_en[] =
3885  {
3886  	MCOMPAT_CONFIG_CHAIN0_START_EN_GPIO,
3887  	MCOMPAT_CONFIG_CHAIN1_START_EN_GPIO,
3888  	MCOMPAT_CONFIG_CHAIN2_START_EN_GPIO,
3889  	MCOMPAT_CONFIG_CHAIN3_START_EN_GPIO,
3890  	MCOMPAT_CONFIG_CHAIN4_START_EN_GPIO,
3891  	MCOMPAT_CONFIG_CHAIN5_START_EN_GPIO,
3892  	MCOMPAT_CONFIG_CHAIN6_START_EN_GPIO,
3893  	MCOMPAT_CONFIG_CHAIN7_START_EN_GPIO
3894  };
3895  
3896  const int pin_reset[] =
3897  {
3898  	MCOMPAT_CONFIG_CHAIN0_RESET_GPIO,
3899  	MCOMPAT_CONFIG_CHAIN1_RESET_GPIO,
3900  	MCOMPAT_CONFIG_CHAIN2_RESET_GPIO,
3901  	MCOMPAT_CONFIG_CHAIN3_RESET_GPIO,
3902  	MCOMPAT_CONFIG_CHAIN4_RESET_GPIO,
3903  	MCOMPAT_CONFIG_CHAIN5_RESET_GPIO,
3904  	MCOMPAT_CONFIG_CHAIN6_RESET_GPIO,
3905  	MCOMPAT_CONFIG_CHAIN7_RESET_GPIO
3906  };
3907  
3908  const int pin_plug[] =
3909  {
3910  	MCOMPAT_CONFIG_CHAIN0_PLUG_GPIO,
3911  	MCOMPAT_CONFIG_CHAIN1_PLUG_GPIO,
3912  	MCOMPAT_CONFIG_CHAIN2_PLUG_GPIO,
3913  	MCOMPAT_CONFIG_CHAIN3_PLUG_GPIO,
3914  	MCOMPAT_CONFIG_CHAIN4_PLUG_GPIO,
3915  	MCOMPAT_CONFIG_CHAIN5_PLUG_GPIO,
3916  	MCOMPAT_CONFIG_CHAIN6_PLUG_GPIO,
3917  	MCOMPAT_CONFIG_CHAIN7_PLUG_GPIO
3918  };
3919  
3920  const int pin_led[] =
3921  {
3922  	MCOMPAT_CONFIG_CHAIN0_LED_GPIO,
3923  	MCOMPAT_CONFIG_CHAIN1_LED_GPIO,
3924  	MCOMPAT_CONFIG_CHAIN2_LED_GPIO,
3925  	MCOMPAT_CONFIG_CHAIN3_LED_GPIO,
3926  	MCOMPAT_CONFIG_CHAIN4_LED_GPIO,
3927  	MCOMPAT_CONFIG_CHAIN5_LED_GPIO,
3928  	MCOMPAT_CONFIG_CHAIN6_LED_GPIO,
3929  	MCOMPAT_CONFIG_CHAIN7_LED_GPIO
3930  };
3931  
3932  
3933  void spi_send_data_in_word(ZYNQ_SPI_T *spi, unsigned char *buf, int len)
3934  {
3935  	int i;
3936  
3937  	for(i = 0; i < len; i = i + 2)
3938  	{
3939  		zynq_spi_write(spi, buf + i, 2);
3940  	}
3941  }
3942  
3943  void spi_recv_data_in_word(ZYNQ_SPI_T *spi, unsigned char *buf, int len)
3944  {
3945  	int i;
3946  
3947  	for(i = 0; i < len; i = i + 2)
3948  	{
3949  		zynq_spi_read(spi, buf + i, 2);
3950  	}
3951  }
3952  
3953  void spi_send_data(ZYNQ_SPI_T *spi, unsigned char *buf, int len)
3954  {
3955  	zynq_spi_write(spi, buf, len);
3956  }
3957  
3958  void spi_recv_data(ZYNQ_SPI_T *spi, unsigned char *buf, int len)
3959  {
3960  	zynq_spi_read(spi, buf, len);
3961  }
3962  
3963  
3964  bool spi_send_command(ZYNQ_SPI_T *spi, unsigned char cmd, unsigned char chip_id, unsigned char *buff, int len)
3965  {
3966  	int tx_len;
3967  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3968  
3969  	if ((len > 0) && (buff == NULL))
3970  	{
3971  		applog(LOG_ERR, "%s,%d: para error !", __FILE__, __LINE__);
3972  		return false;
3973  	}
3974  
3975  	memset(tx_buf, 0, sizeof(tx_buf));
3976  
3977  	tx_buf[0] = cmd;
3978  	tx_buf[1] = chip_id;
3979  
3980  	if (len > 0)
3981  	{
3982  		memcpy(tx_buf + 2, buff, len);
3983  	}
3984  
3985  	tx_len = (2 + len + 1) & ~1;
3986  	//spi_send_data_in_word(spi, tx_buf, tx_len);
3987  	spi_send_data(spi, tx_buf, tx_len);
3988  
3989  	return true;
3990  }
3991  
3992  
3993  bool spi_poll_result(ZYNQ_SPI_T *spi, unsigned char cmd, unsigned char __maybe_unused chip_id, unsigned char *buff, int len)
3994  {
3995  	int i;
3996  	int max_len;
3997  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
3998  
3999  	max_len = g_chip_num * 4;
4000  	memset(rx_buf, 0, sizeof(rx_buf));
4001  
4002  	for(i = 0; i < max_len; i = i + 2)
4003  	{
4004  		spi_recv_data(spi, rx_buf, 2);
4005  		if ((rx_buf[0] & 0x0f) == cmd)
4006  		{
4007  			break;
4008  		}
4009  	}
4010  
4011  	if (i >= max_len)
4012  	{
4013  		applog(LOG_ERR, "%s,%d: poll fail !", __FILE__, __LINE__);
4014  		return false;
4015  	}
4016  
4017  	spi_recv_data_in_word(spi, rx_buf+2, len);
4018  	memcpy(buff, rx_buf, len+2);
4019  
4020  	return true;
4021  }
4022  
4023  
4024  
4025  void init_spi_gpio(int chain_num)
4026  {
4027  	int i;
4028  
4029  	for(i = 0; i < chain_num; i++)
4030  	{
4031  		zynq_gpio_init(pin_power_en[i], 0);
4032  		zynq_gpio_init(pin_start_en[i], 0);
4033  		zynq_gpio_init(pin_reset[i], 0);
4034  		zynq_gpio_init(pin_led[i], 0);
4035  		zynq_gpio_init(pin_plug[i], 1);
4036  	}
4037  }
4038  
4039  void exit_spi_gpio(int chain_num)
4040  {
4041  	int i;
4042  
4043  	for(i = 0; i < chain_num; i++)
4044  	{
4045  		zynq_gpio_exit(pin_power_en[i]);
4046  		zynq_gpio_exit(pin_start_en[i]);
4047  		zynq_gpio_exit(pin_reset[i]);
4048  		zynq_gpio_exit(pin_led[i]);
4049  		zynq_gpio_exit(pin_plug[i]);
4050  	}
4051  }
4052  
4053  
4054  void spi_set_power_en(unsigned char chain_id, int val)
4055  {
4056  	zynq_gpio_write(pin_power_en[chain_id], val);
4057  }
4058  
4059  void spi_set_start_en(unsigned char chain_id, int val)
4060  {
4061  	zynq_gpio_write(pin_start_en[chain_id], val);
4062  }
4063  
4064  bool spi_set_reset(unsigned char chain_id, int val)
4065  {
4066  	return zynq_gpio_write(pin_reset[chain_id], val);
4067  }
4068  
4069  void spi_set_led(unsigned char chain_id, int val)
4070  {
4071  	zynq_gpio_write(pin_led[chain_id], val);
4072  }
4073  
4074  int spi_get_plug(unsigned char chain_id)
4075  {
4076  	return zynq_gpio_read(pin_plug[chain_id]);
4077  }
4078  
4079  static int s_vid = 0;
4080  bool spi_set_vid(unsigned char chain_id, int vid)
4081  {
4082  	if (g_platform == PLATFORM_ZYNQ_SPI_G19)
4083  	{
4084  		zynq_gpio_g19_vid_set(chain_id, vid);
4085  	}
4086  	else if (g_platform == PLATFORM_ZYNQ_SPI_G9)
4087  	{
4088  		if (s_vid != vid)
4089  		{
4090  			zynq_gpio_g9_vid_set(vid);
4091  		}
4092  	}
4093  	else
4094  	{
4095  		applog(LOG_ERR, "platform[%d] error in set vid ", g_platform);
4096  		return false;
4097  	}
4098  
4099  	return true;
4100  }
4101  
4102  void spi_set_spi_speed(unsigned char __maybe_unused chain_id, int index)
4103  {
4104  	uint32_t cfg[] = {390625, 781250, 1562500, 3125000, 6250000, 9960000};
4105  
4106  	zynq_set_spi_speed(cfg[index]);
4107  }
4108  
4109  
4110  bool zynq_chain_power_on(unsigned char chain_id)
4111  {
4112  
4113  	if (mcompat_get_plug(chain_id) != 0)
4114  	{
4115  		applog(LOG_NOTICE, "chain %d >>> the board not inserted !!!", chain_id);
4116  		return false;
4117  	}
4118  
4119  	mcompat_set_power_en(chain_id, 1);
4120  	sleep(5);
4121  	mcompat_set_reset(chain_id, 1);
4122  	sleep(1);
4123  	mcompat_set_start_en(chain_id, 1);
4124  
4125  	return true;
4126  }
4127  
4128  
4129  bool zynq_chain_power_down(unsigned char chain_id)
4130  {
4131  	mcompat_set_power_en(chain_id, 0);
4132  	sleep(1);
4133  	mcompat_set_reset(chain_id, 0);
4134  	mcompat_set_start_en(chain_id, 0);
4135  	mcompat_set_led(chain_id, 1);
4136  
4137  	return true;
4138  }
4139  
4140  
4141  bool zynq_chain_hw_reset(unsigned char chain_id)
4142  {
4143  	mcompat_set_reset(chain_id, 0);
4144  	sleep(1);
4145  	mcompat_set_reset(chain_id, 1);
4146  	sleep(1);
4147  
4148  	return true;
4149  }
4150  
4151  
4152  bool zynq_chain_power_on_all(void)
4153  {
4154  	int i;
4155  
4156  	for(i = 0; i < g_chain_num; i++)
4157  	{
4158  		if (mcompat_get_plug(i) != 0)
4159  		{
4160  			applog(LOG_NOTICE, "chain %d >>> the board not inserted !!! ", i);
4161  		}
4162  	}
4163  
4164  	for(i = 0; i < g_chain_num; i++) {
4165  		mcompat_set_power_en(i, 1);
4166  		cgsleep_ms(5);
4167  	}
4168  
4169  	sleep(5);
4170  
4171  	for(i = 0; i < g_chain_num; i++) {
4172  		mcompat_set_reset(i, 1);
4173  		cgsleep_ms(5);
4174  	}
4175  
4176  	sleep(1);
4177  
4178  	for(i = 0; i < g_chain_num; i++) {
4179  		mcompat_set_start_en(i, 1);
4180  		cgsleep_ms(5);
4181  	}
4182  
4183  	return true;
4184  }
4185  
4186  
4187  bool zynq_chain_power_down_all(void)
4188  {
4189  	int i;
4190  
4191  	for(i = 0; i < g_chain_num; i++) {
4192  		mcompat_set_power_en(i, 0);
4193  	}
4194  
4195  	sleep(1);
4196  
4197  	for(i = 0; i < g_chain_num; i++) {
4198  		mcompat_set_reset(i, 0);
4199  		mcompat_set_start_en(i, 0);
4200  		mcompat_set_led(i, 1);
4201  	}
4202  
4203  	return true;
4204  }
4205  
4206  bool init_hub_cmd(int chain_num, int chip_num)
4207  {
4208  	int i;
4209  
4210  	for(i = 0; i < chain_num; i++)
4211  	{
4212  		hub_spi_init(i, chip_num);
4213  	}
4214  
4215  	return true;
4216  }
4217  
4218  bool exit_hub_cmd(int __maybe_unused chain_num)
4219  {
4220  	return true;
4221  }
4222  
4223  
4224  bool hub_cmd_reset(unsigned char chain_id, unsigned char chip_id, unsigned char *in, unsigned char *out)
4225  {
4226  	uint32_t cfg_len = 0;
4227  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4228  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4229  
4230  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
4231  
4232  	memset(spi_tx, 0, sizeof(spi_tx));
4233  	memset(spi_rx, 0, sizeof(spi_rx));
4234  
4235  	spi_tx[0] = CMD_RESET;
4236  	spi_tx[1] = chip_id;
4237  	spi_tx[2] = in[0];
4238  	spi_tx[3] = in[1];
4239  
4240  	//cfg_len = 0x03000200;
4241  	cfg_len += (0x03) << 24;
4242  	cfg_len += (0x00) << 16;
4243  	cfg_len += (0x02) << 8;
4244  	cfg_len += (0x00) << 0;
4245  
4246  	if (do_spi_cmd(chain_id, spi_tx, spi_rx, cfg_len) == XST_FAILURE)
4247  	{
4248  		return false;
4249  	}
4250  
4251  	//print_data_hex("tx:", spi_tx, 8);
4252  	//print_data_hex("rx:", spi_rx, 8);
4253  	memcpy(out, spi_rx, 4);
4254  
4255  	return true;
4256  }
4257  
4258  
4259  int hub_cmd_bist_start(unsigned char chain_id, unsigned char chip_id)
4260  {
4261  	uint32_t cfg_len = 0;
4262  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4263  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4264  
4265  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
4266  
4267  	memset(spi_tx, 0, sizeof(spi_tx));
4268  	memset(spi_rx, 0, sizeof(spi_rx));
4269  
4270  	spi_tx[0] = CMD_BIST_START;
4271  	spi_tx[1] = chip_id;
4272  
4273  	//cfg_len = 0x02000200;
4274  	cfg_len += (0x02) << 24;
4275  	cfg_len += (0x00) << 16;
4276  	cfg_len += (0x02) << 8;
4277  	cfg_len += (0x00) << 0;
4278  
4279  	if (do_spi_cmd(chain_id, spi_tx, spi_rx, cfg_len) == XST_FAILURE)
4280  	{
4281  		return -1;
4282  	}
4283  
4284  	//print_data_hex("tx:", spi_tx, 8);
4285  	//print_data_hex("rx:", spi_rx, 8);
4286  
4287  	return spi_rx[3];;
4288  }
4289  
4290  
4291  bool hub_cmd_bist_collect(unsigned char chain_id, unsigned char chip_id)
4292  {
4293  	uint32_t cfg_len = 0;
4294  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4295  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4296  
4297  	memset(spi_tx, 0, sizeof(spi_tx));
4298  	memset(spi_rx, 0, sizeof(spi_rx));
4299  
4300  	spi_tx[0] = CMD_BIST_COLLECT;
4301  	spi_tx[1] = chip_id;
4302  
4303  	//cfg_len = 0x02000200;
4304  	cfg_len += (0x02) << 24;
4305  	cfg_len += (0x00) << 16;
4306  	cfg_len += (0x02) << 8;
4307  	cfg_len += (0x00) << 0;
4308  
4309  	if (do_spi_cmd(chain_id, spi_tx, spi_rx, cfg_len) == XST_FAILURE)
4310  	{
4311  		return false;
4312  	}
4313  
4314  	return true;
4315  }
4316  
4317  
4318  bool hub_cmd_bist_fix(unsigned char chain_id, unsigned char chip_id)
4319  {
4320  	uint32_t cfg_len = 0;
4321  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4322  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4323  
4324  	memset(spi_tx, 0, sizeof(spi_tx));
4325  	memset(spi_rx, 0, sizeof(spi_rx));
4326  
4327  	spi_tx[0] = CMD_BIST_FIX;
4328  	spi_tx[1] = chip_id;
4329  
4330  	//cfg_len = 0x02000200;
4331  	cfg_len += (0x02) << 24;
4332  	cfg_len += (0x00) << 16;
4333  	cfg_len += (0x02) << 8;
4334  	cfg_len += (0x00) << 0;
4335  
4336  	if (do_spi_cmd(chain_id, spi_tx, spi_rx, cfg_len) == XST_FAILURE)
4337  	{
4338  		return false;
4339  	}
4340  
4341  	return true;
4342  }
4343  
4344  
4345  bool hub_cmd_write_register(unsigned char chain_id, unsigned char chip_id, unsigned char *reg, int len)
4346  {
4347  	uint32_t cfg_len = 0;
4348  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4349  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4350  
4351  	memset(spi_tx, 0, sizeof(spi_tx));
4352  	memset(spi_rx, 0, sizeof(spi_rx));
4353  
4354  	spi_tx[0] = CMD_WRITE_REG;
4355  	spi_tx[1] = chip_id;
4356  	memcpy(spi_tx + 2, reg, len);
4357  
4358  	//cfg_len = 0x09070807;
4359  	cfg_len += (((len / 2) + 2) & 0xff) << 24;
4360  	cfg_len += (((len / 2) + 1) & 0xff) << 16;
4361  	cfg_len += (((len / 2) + 2) & 0xff) << 8;
4362  	cfg_len += (((len / 2) + 1) & 0xff) << 0;
4363  
4364  	if (do_spi_cmd(chain_id, spi_tx, spi_rx, cfg_len) == XST_FAILURE)
4365  	{
4366  		return false;
4367  	}
4368  
4369  	return true;
4370  }
4371  
4372  
4373  bool hub_cmd_read_register(unsigned char chain_id, unsigned char chip_id, unsigned char *reg, int len)
4374  {
4375  	uint32_t cfg_len = 0;
4376  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4377  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4378  	int i;
4379  	unsigned short crc1, crc2;
4380  	uint8_t tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4381  
4382  	memset(spi_tx, 0, sizeof(spi_tx));
4383  	memset(spi_rx, 0, sizeof(spi_rx));
4384  
4385  	spi_tx[0] = CMD_READ_REG;
4386  	spi_tx[1] = chip_id;
4387  
4388  	//cfg_len = 0x02000807;
4389  	cfg_len += (0x02) << 24;
4390  	cfg_len += (0x00) << 16;
4391  	cfg_len += (((len / 2) + 2) & 0xff) << 8;
4392  	cfg_len += (((len / 2) + 1) & 0xff) << 0;
4393  
4394  	if (do_spi_cmd(chain_id, spi_tx, spi_rx, cfg_len) == XST_FAILURE)
4395  	{
4396  		return false;
4397  	}
4398  
4399  	for(i = 0; i < len + 2; i = i + 2)
4400  	{
4401  		tmp_buf[i + 0] = spi_rx[i + 1];
4402  		tmp_buf[i + 1] = spi_rx[i + 0];
4403  	}
4404  	crc1 = CRC16_2(tmp_buf, len + 2);
4405  	crc2 = (spi_rx[2 + len + 0] << 8) + (spi_rx[2 + len + 1] << 0);
4406  
4407  	if (crc1 != crc2) {
4408  		applog(LOG_WARNING, "%s crc error !", __FUNCTION__);
4409  		return false;
4410  	}
4411  
4412  	memcpy(reg, spi_rx + 2, len);
4413  
4414  	return true;
4415  }
4416  
4417  
4418  bool hub_cmd_read_write_reg0d(unsigned char chain_id, unsigned char chip_id, unsigned char *in, int len, unsigned char *out)
4419  {
4420  	uint32_t cfg_len = 0;
4421  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4422  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4423  	int i;
4424  	unsigned short crc1, crc2;
4425  	uint8_t tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4426  
4427  	memset(spi_tx, 0, sizeof(spi_tx));
4428  	memset(spi_rx, 0, sizeof(spi_rx));
4429  
4430  	spi_tx[0] = CMD_WRITE_REG0d;
4431  	spi_tx[1] = chip_id;
4432  	memcpy(spi_tx + 2, in, len);
4433  
4434  	//cfg_len = 0x09070807;
4435  	cfg_len += (((len / 2) + 2) & 0xff) << 24;
4436  	cfg_len += (((len / 2) + 1) & 0xff) << 16;
4437  	cfg_len += (((len / 2) + 2) & 0xff) << 8;
4438  	cfg_len += (((len / 2) + 1) & 0xff) << 0;
4439  
4440  	if (do_spi_cmd(chain_id, spi_tx, spi_rx, cfg_len) == XST_FAILURE)
4441  	{
4442  		return false;
4443  	}
4444  
4445  	for(i = 0; i < len + 2; i = i + 2)
4446  	{
4447  		tmp_buf[i + 0] = spi_rx[i + 1];
4448  		tmp_buf[i + 1] = spi_rx[i + 0];
4449  	}
4450  	crc1 = CRC16_2(tmp_buf, len + 2);
4451  	crc2 = (spi_rx[2 + len + 0] << 8) + (spi_rx[2 + len + 1] << 0);
4452  
4453  	if (crc1 != crc2) {
4454  		applog(LOG_WARNING, "%s crc error !", __FUNCTION__);
4455  		return false;
4456  	}
4457  
4458  	memcpy(out, spi_rx + 2, len);
4459  
4460  	return true;
4461  }
4462  
4463  bool hub_cmd_write_job(unsigned char chain_id, unsigned char chip_id, unsigned char *job, int len)
4464  {
4465  	uint32_t cfg_len = 0;
4466  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4467  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4468  
4469  	memset(spi_tx, 0, sizeof(spi_tx));
4470  	memset(spi_rx, 0, sizeof(spi_rx));
4471  
4472  	memcpy(spi_tx, job, len);
4473  	//cfg_len = 0x504f0000;
4474  	cfg_len += (((len / 2) + 1) & 0xff) << 24;
4475  	cfg_len += (((len / 2) - 1) & 0xff) << 16;
4476  	cfg_len += (0x00) << 8;
4477  	cfg_len += (0x00) << 0;
4478  
4479  	if (send_job_queue(chain_id, spi_tx, spi_rx, cfg_len, (chip_id == 1)) == XST_FAILURE)
4480  	{
4481  		return false;
4482  	}
4483  
4484  	return true;
4485  }
4486  
4487  
4488  bool hub_cmd_read_result(unsigned char chain_id, unsigned char chip_id, unsigned char *res, int len)
4489  {
4490  	uint32_t cfg_len = 0;
4491  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4492  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4493  	int i;
4494  	unsigned short crc1, crc2;
4495  	uint8_t tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4496  
4497  	memset(spi_tx, 0, sizeof(spi_tx));
4498  	memset(spi_rx, 0, sizeof(spi_rx));
4499  
4500  	spi_tx[0] = CMD_READ_RESULT;
4501  	spi_tx[1] = chip_id;
4502  
4503  //	cfg_len = 0x02000605;
4504  	cfg_len += (0x02) << 24;
4505  	cfg_len += (0x00) << 16;
4506  	cfg_len += (((len / 2) + 3) & 0xff) << 8;
4507  	cfg_len += (((len / 2) + 2) & 0xff) << 0;
4508  
4509  	if (do_spi_cmd(chain_id, spi_tx, spi_rx, cfg_len) == XST_FAILURE)
4510  		return false;
4511  
4512  	if (spi_rx[1] == 0)
4513  		return false;
4514  
4515  	for (i = 0; i < len + 2; i = i + 2) {
4516  		tmp_buf[i + 0] = spi_rx[i + 1];
4517  		tmp_buf[i + 1] = spi_rx[i + 0];
4518  	}
4519  	crc1 = CRC16_2(tmp_buf, len + 2);
4520  	crc2 = (spi_rx[2 + len + 0] << 8) + (spi_rx[2 + len + 1] << 0);
4521  
4522  	if (crc1 != crc2) {
4523  		applog(LOG_WARNING, "%s crc error !", __FUNCTION__);
4524  		return false;
4525  	}
4526  
4527  	memcpy(res, spi_rx, len + 2);
4528  
4529  	return true;
4530  }
4531  
4532  
4533  bool hub_cmd_auto_nonce(unsigned char chain_id, int mode, int len)
4534  {
4535  	uint16_t cmd08 = 0x0800;
4536  	uint32_t cfg_len = 0;
4537  
4538  //	cfg_len = 0x02000605;
4539  	cfg_len += (0x02) << 24;
4540  	cfg_len += (0x00) << 16;
4541  	cfg_len += (((len / 2) + 3) & 0xff) << 8;
4542  	cfg_len += (((len / 2) + 2) & 0xff) << 0;
4543  
4544  	if (mode == 0)
4545  		disable_auto_nonce(chain_id);
4546  	else
4547  		enable_auto_nonce(chain_id, cmd08, cfg_len);
4548  
4549  	return true;
4550  }
4551  
4552  bool hub_cmd_read_nonce(unsigned char chain_id, unsigned char *res, int len)
4553  {
4554  	uint32_t cfg_len = 0;
4555  	uint8_t spi_tx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4556  	uint8_t spi_rx[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4557  
4558  	memset(spi_tx, 0, sizeof(spi_tx));
4559  	memset(spi_rx, 0, sizeof(spi_rx));
4560  
4561  //	cfg_len = 0x02000605;
4562  	cfg_len += (0x02) << 24;
4563  	cfg_len += (0x00) << 16;
4564  	cfg_len += (((len / 2) + 3) & 0xff) << 8;
4565  	cfg_len += (((len / 2) + 2) & 0xff) << 0;
4566  
4567  	if (!rece_queue_has_nonce(chain_id, 1000))
4568  		return false;
4569  
4570  	read_nonce_buffer(chain_id, spi_rx, cfg_len);
4571  
4572  	if (spi_rx[1] == 0)
4573  		return false;
4574  
4575  	//print_data_hex("read_nonce rx:", spi_rx, len + 2);
4576  	memcpy(res, spi_rx, len + 2);
4577  
4578  	return true;
4579  }
4580  
4581  
4582  bool hub_cmd_get_temp(mcompat_fan_temp_s *fan_temp_ctrl,unsigned char chain_id)
4583  {
4584  	uint32_t val;
4585  
4586  	if (hub_get_plug(chain_id))
4587  		return false;
4588  
4589  	enable_auto_cmd0a(chain_id,g_dangerous_temp,33,24,0,0);
4590  	mcompat_temp_s *temp_ctrl = &fan_temp_ctrl->mcompat_temp[chain_id];
4591  
4592  	do{
4593  		val = Xil_SPI_In32(SPI_AXIBASE + SPI_BASEADDR_GAP*chain_id+AUTO_CMD0A_REG4_ADDR);
4594  	}while(!((val >> 24) & 0x1));
4595  
4596  	hub_get_hitemp_stat(chain_id,temp_ctrl);
4597  	hub_get_lotemp_stat(chain_id,temp_ctrl);
4598  	hub_get_avgtemp_stat(chain_id,temp_ctrl);
4599  	disable_auto_cmd0a(chain_id,g_dangerous_temp,33,24,0,0);
4600  
4601  
4602  	return true;
4603  }
4604  
4605  
4606  bool init_opi_cmd(void)
4607  {
4608  	opi_spi_init();
4609  
4610  	return true;
4611  }
4612  
4613  bool exit_opi_cmd(void)
4614  {
4615  	opi_spi_exit();
4616  
4617  	return true;
4618  }
4619  
4620  
4621  bool opi_cmd_reset(unsigned char chain_id, unsigned char chip_id, unsigned char *in, unsigned char *out)
4622  {
4623  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4624  
4625  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
4626  
4627  	if (!opi_send_command(chain_id, CMD_RESET, chip_id, in, 2))
4628  	{
4629  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
4630  		return false;
4631  	}
4632  
4633  	memset(rx_buf, 0, sizeof(rx_buf));
4634  	if (!opi_poll_result(chain_id, CMD_RESET, chip_id, rx_buf, 2))
4635  	{
4636  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
4637  		return false;
4638  	}
4639  
4640  	memcpy(out, rx_buf, 4);
4641  
4642  	return true;
4643  }
4644  
4645  
4646  int opi_cmd_bist_start(unsigned char chain_id, unsigned char chip_id)
4647  {
4648  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4649  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4650  
4651  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
4652  
4653  	memset(tx_buf, 0, sizeof(tx_buf));
4654  	if (!opi_send_command(chain_id, CMD_BIST_START, chip_id, tx_buf, 2))
4655  	{
4656  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
4657  		return -1;
4658  	}
4659  
4660  	memset(rx_buf, 0, sizeof(rx_buf));
4661  	if (!opi_poll_result(chain_id, CMD_BIST_START, chip_id, rx_buf, 2))
4662  	{
4663  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
4664  		return -1;
4665  	}
4666  
4667  	return rx_buf[3];
4668  }
4669  
4670  
4671  bool opi_cmd_bist_collect(unsigned char chain_id, unsigned char chip_id)
4672  {
4673  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4674  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4675  
4676  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
4677  
4678  	memset(tx_buf, 0, sizeof(tx_buf));
4679  	if (!opi_send_command(chain_id, CMD_BIST_COLLECT, chip_id, tx_buf, 2))
4680  	{
4681  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
4682  		return false;
4683  	}
4684  
4685  	memset(rx_buf, 0, sizeof(rx_buf));
4686  	if (!opi_poll_result(chain_id, CMD_BIST_COLLECT, chip_id, rx_buf, 2))
4687  	{
4688  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
4689  		return false;
4690  	}
4691  
4692  	return true;
4693  }
4694  
4695  
4696  bool opi_cmd_bist_fix(unsigned char chain_id, unsigned char chip_id)
4697  {
4698  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4699  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4700  
4701  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
4702  
4703  	memset(tx_buf, 0, sizeof(tx_buf));
4704  	if (!opi_send_command(chain_id, CMD_BIST_FIX, chip_id, tx_buf, 2))
4705  	{
4706  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
4707  		return false;
4708  	}
4709  
4710  	memset(rx_buf, 0, sizeof(rx_buf));
4711  	if (!opi_poll_result(chain_id, CMD_BIST_FIX, chip_id, rx_buf, 2))
4712  	{
4713  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
4714  		return false;
4715  	}
4716  
4717  	return true;
4718  }
4719  
4720  
4721  bool opi_cmd_write_register(unsigned char chain_id, unsigned char chip_id, unsigned char *reg, int len)
4722  {
4723  	int i;
4724  	unsigned short crc;
4725  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4726  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4727  	unsigned char tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4728  
4729  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
4730  
4731  	if (reg == NULL)
4732  	{
4733  		applog(LOG_ERR, "%s,%d: %s para error !", __FILE__, __LINE__, __FUNCTION__);
4734  		return false;
4735  	}
4736  
4737  	memset(tx_buf, 0, sizeof(tx_buf));
4738  	tx_buf[0] = OPI_HI_BYTE(AX_CMD_SYNC_HEAD);
4739  	tx_buf[1] = OPI_LO_BYTE(AX_CMD_SYNC_HEAD);
4740  	tx_buf[2] = CMD_WRITE_REG;
4741  	tx_buf[3] = chip_id;
4742  	memcpy(tx_buf + 4, reg, len);
4743  	for(i = 0; i < len + 2; i = i + 2)
4744  	{
4745  		tmp_buf[i + 0] = tx_buf[i + 1 + 2];
4746  		tmp_buf[i + 1] = tx_buf[i + 0 + 2];
4747  	}
4748  	crc = CRC16_2(tmp_buf, len + 2);
4749  	tx_buf[4 + len + 0] = (unsigned char)((crc >> 8) & 0xff);
4750  	tx_buf[4 + len + 1] = (unsigned char)((crc >> 0) & 0xff);
4751  
4752  	opi_spi_read_write(chain_id, tx_buf, rx_buf, len + 6);
4753  
4754  	memset(rx_buf, 0, sizeof(rx_buf));
4755  	if (!opi_poll_result(chain_id, CMD_WRITE_REG, chip_id, rx_buf, len))
4756  	{
4757  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
4758  		return false;
4759  	}
4760  
4761  	return true;
4762  }
4763  
4764  bool opi_cmd_read_register(unsigned char chain_id, unsigned char chip_id, unsigned char *reg, int len)
4765  {
4766  	int i;
4767  	int max_len;
4768  	unsigned short crc1, crc2;
4769  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4770  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4771  	unsigned char tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4772  
4773  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
4774  
4775  	if (reg == NULL)
4776  	{
4777  		applog(LOG_ERR, "%s,%d: %s para error !", __FILE__, __LINE__, __FUNCTION__);
4778  		return false;
4779  	}
4780  
4781  	memset(tx_buf, 0, sizeof(tx_buf));
4782  	if (!opi_send_command(chain_id, CMD_READ_REG, chip_id, tx_buf, 0))
4783  	{
4784  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
4785  		return false;
4786  	}
4787  
4788  	max_len = g_chip_num * 4;
4789  	memset(rx_buf, 0, sizeof(rx_buf));
4790  
4791  	for(i = 0; i < max_len; i = i + 2)
4792  	{
4793  		opi_spi_read_write(chain_id, NULL, rx_buf, 2);
4794  		if ((rx_buf[0] & 0x0f) == CMD_READ_REG)
4795  		{
4796  			break;
4797  		}
4798  	}
4799  
4800  	if (i >= max_len)
4801  	{
4802  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
4803  		return false;
4804  	}
4805  
4806  	opi_spi_read_write(chain_id, NULL, rx_buf + 2, len + 2);
4807  
4808  	for(i = 0; i < len + 2; i = i + 2)
4809  	{
4810  		tmp_buf[i + 0] = rx_buf[i + 1];
4811  		tmp_buf[i + 1] = rx_buf[i + 0];
4812  	}
4813  	crc1 = CRC16_2(tmp_buf, len + 2);
4814  	crc2 = (rx_buf[2 + len + 0] << 8) + (rx_buf[2 + len + 1] << 0);
4815  
4816  	if (crc1 != crc2)
4817  	{
4818  		applog(LOG_WARNING, "%s,%d: %s crc fail !", __FILE__, __LINE__, __FUNCTION__);
4819  		return false;
4820  	}
4821  
4822  	memcpy(reg, rx_buf + 2, len);
4823  
4824  	return true;
4825  }
4826  
4827  
4828  bool opi_cmd_read_write_reg0d(unsigned char chain_id, unsigned char chip_id, unsigned char *in, int len, unsigned char *out)
4829  {
4830  	int i;
4831  	int max_len;
4832  	unsigned short crc;
4833  	unsigned short crc1, crc2;
4834  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4835  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4836  	unsigned char tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4837  
4838  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
4839  
4840  	if ((in == NULL) || (out == NULL))
4841  	{
4842  		applog(LOG_ERR, "%s,%d: %s para error !", __FILE__, __LINE__, __FUNCTION__);
4843  		return false;
4844  	}
4845  
4846  	memset(tx_buf, 0, sizeof(tx_buf));
4847  	tx_buf[0] = OPI_HI_BYTE(AX_CMD_SYNC_HEAD);
4848  	tx_buf[1] = OPI_LO_BYTE(AX_CMD_SYNC_HEAD);
4849  	tx_buf[2] = CMD_WRITE_REG0d;
4850  	tx_buf[3] = chip_id;
4851  	memcpy(tx_buf + 4, in, len);
4852  	for(i = 0; i < len + 2; i = i + 2)
4853  	{
4854  		tmp_buf[i + 0] = tx_buf[i + 1 + 2];
4855  		tmp_buf[i + 1] = tx_buf[i + 0 + 2];
4856  	}
4857  	crc = CRC16_2(tmp_buf, len + 2);
4858  	tx_buf[4 + len + 0] = (unsigned char)((crc >> 8) & 0xff);
4859  	tx_buf[4 + len + 1] = (unsigned char)((crc >> 0) & 0xff);
4860  
4861  	opi_spi_read_write(chain_id, tx_buf, rx_buf, len + 6);
4862  
4863  	max_len = g_chip_num * 4;
4864  	memset(rx_buf, 0, sizeof(rx_buf));
4865  
4866  	for(i = 0; i < max_len; i = i + 2)
4867  	{
4868  		opi_spi_read_write(chain_id, NULL, rx_buf, 2);
4869  		if ((rx_buf[0] & 0x0f) == CMD_WRITE_REG0d)
4870  		{
4871  			break;
4872  		}
4873  	}
4874  
4875  	if (i >= max_len)
4876  	{
4877  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
4878  		return false;
4879  	}
4880  
4881  	opi_spi_read_write(chain_id, NULL, rx_buf + 2, len + 2);
4882  
4883  	for(i = 0; i < len + 2; i = i + 2)
4884  	{
4885  		tmp_buf[i + 0] = rx_buf[i + 1];
4886  		tmp_buf[i + 1] = rx_buf[i + 0];
4887  	}
4888  	crc1 = CRC16_2(tmp_buf, len + 2);
4889  	crc2 = (rx_buf[2 + len + 0] << 8) + (rx_buf[2 + len + 1] << 0);
4890  
4891  	if (crc1 != crc2)
4892  	{
4893  		applog(LOG_WARNING, "%s,%d: %s crc fail !", __FILE__, __LINE__, __FUNCTION__);
4894  		return false;
4895  	}
4896  
4897  	memcpy(out, rx_buf + 2, len);
4898  
4899  	return true;
4900  }
4901  
4902  
4903  bool opi_cmd_read_result(unsigned char chain_id, unsigned char chip_id, unsigned char *res, int len)
4904  {
4905  	int i;
4906  	int max_len;
4907  	unsigned short crc1, crc2;
4908  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4909  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4910  	unsigned char tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
4911  
4912  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
4913  
4914  	if (res == NULL)
4915  	{
4916  		applog(LOG_ERR, "%s,%d: %s para error !", __FILE__, __LINE__, __FUNCTION__);
4917  		return false;
4918  	}
4919  
4920  	memset(tx_buf, 0, sizeof(tx_buf));
4921  	if (!opi_send_command(chain_id, CMD_READ_RESULT, chip_id, tx_buf, 2))
4922  	{
4923  		applog(LOG_WARNING, "%s,%d: %s send fail !", __FILE__, __LINE__, __FUNCTION__);
4924  		return false;
4925  	}
4926  
4927  	max_len = g_chip_num * 4;
4928  	memset(rx_buf, 0, sizeof(rx_buf));
4929  
4930  	for(i = 0; i < max_len; i = i + 2)
4931  	{
4932  		opi_spi_read_write(chain_id, NULL, rx_buf, 2);
4933  		if (((rx_buf[0] & 0x0f) == CMD_READ_RESULT) && (rx_buf[1] != 0))
4934  		{
4935  			break;
4936  		}
4937  	}
4938  
4939  	if (i >= max_len)
4940  	{
4941  		applog(LOG_WARNING, "%s,%d: %s poll fail !", __FILE__, __LINE__, __FUNCTION__);
4942  		return false;
4943  	}
4944  
4945  	opi_spi_read_write(chain_id, NULL, rx_buf + 2, len + 2);
4946  
4947  	for(i = 0; i < len + 2; i = i + 2)
4948  	{
4949  		tmp_buf[i + 0] = rx_buf[i + 1];
4950  		tmp_buf[i + 1] = rx_buf[i + 0];
4951  	}
4952  	crc1 = CRC16_2(tmp_buf, len + 2);
4953  	crc2 = (rx_buf[2 + len + 0] << 8) + (rx_buf[2 + len + 1] << 0);
4954  
4955  	if (crc1 != crc2)
4956  	{
4957  		applog(LOG_WARNING, "%s,%d: %s crc fail !", __FILE__, __LINE__, __FUNCTION__);
4958  		return false;
4959  	}
4960  
4961  	memcpy(res, rx_buf, len + 2);
4962  
4963  	return true;
4964  }
4965  
4966  
4967  bool opi_cmd_write_job(unsigned char chain_id, unsigned char chip_id, unsigned char *job, int len)
4968  {
4969  	applog(LOG_DEBUG, "%s,%d: %s(%d, %d, %p, %d)", __FILE__, __LINE__, __FUNCTION__, chain_id, chip_id, job, len);
4970  
4971  	if (job == NULL)
4972  	{
4973  		applog(LOG_ERR, "%s,%d: %s para error !", __FILE__, __LINE__, __FUNCTION__);
4974  		return false;
4975  	}
4976  
4977  	return opi_spi_read_write(chain_id, NULL, job, len);
4978  }
4979  
4980  
4981  ZYNQ_SPI_T s_spi[MCOMPAT_CONFIG_MAX_CHAIN_NUM];
4982  
4983  bool init_spi_cmd(int chain_num)
4984  {
4985  	int i;
4986  
4987  	for(i = 0; i < chain_num; i++)
4988  	{
4989  		memset((void*)&s_spi[i], 0, sizeof(ZYNQ_SPI_T));
4990  		zynq_spi_init(&s_spi[i], i);
4991  	}
4992  
4993  	return true;
4994  }
4995  
4996  bool exit_spi_cmd(int chain_num)
4997  {
4998  	int i;
4999  
5000  	for(i = 0; i < chain_num; i++)
5001  	{
5002  		zynq_spi_exit(&s_spi[i]);
5003  	}
5004  
5005  	return true;
5006  }
5007  
5008  bool spi_cmd_reset(unsigned char chain_id, unsigned char chip_id, unsigned char *in, unsigned char *out)
5009  {
5010  	ZYNQ_SPI_T *spi = &s_spi[chain_id];
5011  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5012  
5013  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
5014  
5015  	if (!spi_send_command(spi, CMD_RESET, chip_id, in, 2))
5016  	{
5017  		applog(LOG_WARNING, "%s send fail !", __FUNCTION__);
5018  		return false;
5019  	}
5020  
5021  	memset(rx_buf, 0, sizeof(rx_buf));
5022  	if (!spi_poll_result(spi, CMD_RESET, chip_id, rx_buf, 2))
5023  	{
5024  		applog(LOG_WARNING, "%s poll fail !", __FUNCTION__);
5025  		return false;
5026  	}
5027  
5028  	memcpy(out, rx_buf, 4);
5029  
5030  	return true;
5031  }
5032  
5033  
5034  int spi_cmd_bist_start(unsigned char chain_id, unsigned char chip_id)
5035  {
5036  	ZYNQ_SPI_T *spi = &s_spi[chain_id];
5037  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5038  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5039  
5040  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
5041  
5042  	memset(tx_buf, 0, sizeof(tx_buf));
5043  	if (!spi_send_command(spi, CMD_BIST_START, chip_id, tx_buf, 2))
5044  	{
5045  		applog(LOG_WARNING, "%s send fail !", __FUNCTION__);
5046  		return -1;
5047  	}
5048  
5049  	memset(rx_buf, 0, sizeof(rx_buf));
5050  	if (!spi_poll_result(spi, CMD_BIST_START, chip_id, rx_buf, 2))
5051  	{
5052  		applog(LOG_WARNING, "%s poll fail !", __FUNCTION__);
5053  		return -1;
5054  	}
5055  
5056  	return rx_buf[3];
5057  }
5058  
5059  bool spi_cmd_bist_collect(unsigned char chain_id, unsigned char chip_id)
5060  {
5061  	ZYNQ_SPI_T *spi = &s_spi[chain_id];
5062  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5063  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5064  
5065  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
5066  
5067  	memset(tx_buf, 0, sizeof(tx_buf));
5068  	if (!spi_send_command(spi, CMD_BIST_COLLECT, chip_id, tx_buf, 2))
5069  	{
5070  		applog(LOG_WARNING, "%s send fail !", __FUNCTION__);
5071  		return false;
5072  	}
5073  
5074  	memset(rx_buf, 0, sizeof(rx_buf));
5075  	if (!spi_poll_result(spi, CMD_BIST_COLLECT, chip_id, rx_buf, 2))
5076  	{
5077  		applog(LOG_WARNING, "%s poll fail !", __FUNCTION__);
5078  		return false;
5079  	}
5080  
5081  	return true;
5082  }
5083  
5084  
5085  bool spi_cmd_bist_fix(unsigned char chain_id, unsigned char chip_id)
5086  {
5087  	ZYNQ_SPI_T *spi = &s_spi[chain_id];
5088  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5089  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5090  
5091  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
5092  
5093  	memset(tx_buf, 0, sizeof(tx_buf));
5094  	if (!spi_send_command(spi, CMD_BIST_FIX, chip_id, tx_buf, 2))
5095  	{
5096  		applog(LOG_WARNING, "%s send fail !", __FUNCTION__);
5097  		return false;
5098  	}
5099  
5100  	memset(rx_buf, 0, sizeof(rx_buf));
5101  	if (!spi_poll_result(spi, CMD_BIST_FIX, chip_id, rx_buf, 2))
5102  	{
5103  		applog(LOG_WARNING, "%s poll fail !", __FUNCTION__);
5104  		return false;
5105  	}
5106  
5107  	return true;
5108  }
5109  
5110  
5111  bool spi_cmd_write_register(unsigned char chain_id, unsigned char chip_id, unsigned char *reg, int len)
5112  {
5113  	int i;
5114  	unsigned short crc;
5115  	ZYNQ_SPI_T *spi = &s_spi[chain_id];
5116  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5117  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5118  	unsigned char tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5119  
5120  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
5121  
5122  	if (reg == NULL)
5123  	{
5124  		applog(LOG_ERR, "%s para error !", __FUNCTION__);
5125  		return false;
5126  	}
5127  
5128  	memset(tx_buf, 0, sizeof(tx_buf));
5129  	tx_buf[0] = CMD_WRITE_REG;
5130  	tx_buf[1] = chip_id;
5131  	memcpy(tx_buf + 2, reg, len);
5132  	for(i = 0; i < len + 2; i = i + 2)
5133  	{
5134  		tmp_buf[i + 0] = tx_buf[i + 1];
5135  		tmp_buf[i + 1] = tx_buf[i + 0];
5136  	}
5137  	crc = CRC16_2(tmp_buf, len + 2);
5138  	tx_buf[2 + len + 0] = (unsigned char)((crc >> 8) & 0xff);
5139  	tx_buf[2 + len + 1] = (unsigned char)((crc >> 0) & 0xff);
5140  
5141  	spi_send_data(spi, tx_buf, len + 4);
5142  
5143  	memset(rx_buf, 0, sizeof(rx_buf));
5144  	if (!spi_poll_result(spi, CMD_WRITE_REG, chip_id, rx_buf, len))
5145  	{
5146  		applog(LOG_WARNING, "%s poll fail !", __FUNCTION__);
5147  		return false;
5148  	}
5149  
5150  	return true;
5151  }
5152  
5153  
5154  bool spi_cmd_read_register(unsigned char chain_id, unsigned char chip_id, unsigned char *reg, int len)
5155  {
5156  	int i;
5157  	int max_len;
5158  	unsigned short crc1, crc2;
5159  	ZYNQ_SPI_T *spi = &s_spi[chain_id];
5160  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5161  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5162  	unsigned char tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5163  
5164  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
5165  
5166  	if (reg == NULL)
5167  	{
5168  		applog(LOG_ERR, "%s para error !", __FUNCTION__);
5169  		return false;
5170  	}
5171  
5172  	memset(tx_buf, 0, sizeof(tx_buf));
5173  	if (!spi_send_command(spi, CMD_READ_REG, chip_id, tx_buf, 0))
5174  	{
5175  		applog(LOG_WARNING, "%s send fail !", __FUNCTION__);
5176  		return false;
5177  	}
5178  
5179  	max_len = g_chip_num * 4;
5180  	memset(rx_buf, 0, sizeof(rx_buf));
5181  
5182  	for(i = 0; i < max_len; i = i + 2)
5183  	{
5184  		spi_recv_data(spi, rx_buf, 2);
5185  		if (rx_buf[0] == RESP_READ_REG)
5186  		{
5187  			break;
5188  		}
5189  	}
5190  
5191  	if (i >= max_len)
5192  	{
5193  		applog(LOG_WARNING, "%s poll fail !", __FUNCTION__);
5194  		return false;
5195  	}
5196  
5197  	spi_recv_data_in_word(spi, rx_buf + 2, len + 2);
5198  
5199  	for(i = 0; i < len + 2; i = i + 2)
5200  	{
5201  		tmp_buf[i + 0] = rx_buf[i + 1];
5202  		tmp_buf[i + 1] = rx_buf[i + 0];
5203  	}
5204  	crc1 = CRC16_2(tmp_buf, len + 2);
5205  	crc2 = (rx_buf[2 + len + 0] << 8) + (rx_buf[2 + len + 1] << 0);
5206  
5207  	if (crc1 != crc2) {
5208  		applog(LOG_WARNING, "%s crc error !", __FUNCTION__);
5209  		return false;
5210  	}
5211  
5212  	memcpy(reg, rx_buf + 2, len);
5213  
5214  	return true;
5215  }
5216  
5217  
5218  bool spi_cmd_read_write_reg0d(unsigned char chain_id, unsigned char chip_id, unsigned char *in, int len, unsigned char *out)
5219  {
5220  	int i;
5221  	int max_len;
5222  	unsigned short crc;
5223  	unsigned short crc1, crc2;
5224  	ZYNQ_SPI_T *spi = &s_spi[chain_id];
5225  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5226  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5227  	unsigned char tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5228  
5229  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
5230  
5231  	if ((in == NULL) || (out == NULL))
5232  	{
5233  		applog(LOG_ERR, "%s para error !", __FUNCTION__);
5234  		return false;
5235  	}
5236  
5237  	memset(tx_buf, 0, sizeof(tx_buf));
5238  	tx_buf[0] = CMD_WRITE_REG0d;
5239  	tx_buf[1] = chip_id;
5240  	memcpy(tx_buf + 2, in, len);
5241  	for(i = 0; i < len + 2; i = i + 2)
5242  	{
5243  		tmp_buf[i + 0] = tx_buf[i + 1];
5244  		tmp_buf[i + 1] = tx_buf[i + 0];
5245  	}
5246  	crc = CRC16_2(tmp_buf, len + 2);
5247  	tx_buf[2 + len + 0] = (unsigned char)((crc >> 8) & 0xff);
5248  	tx_buf[2 + len + 1] = (unsigned char)((crc >> 0) & 0xff);
5249  
5250  	spi_send_data(spi, tx_buf, len + 4);
5251  
5252  	max_len = g_chip_num * 4;
5253  	memset(rx_buf, 0, sizeof(rx_buf));
5254  
5255  	for(i = 0; i < max_len; i = i + 2)
5256  	{
5257  		spi_recv_data(spi, rx_buf, 2);
5258  		if ((rx_buf[0] & 0x0f) == CMD_WRITE_REG0d)
5259  		{
5260  			break;
5261  		}
5262  	}
5263  
5264  	if (i >= max_len)
5265  	{
5266  		applog(LOG_WARNING, "%s poll fail !", __FUNCTION__);
5267  		return false;
5268  	}
5269  
5270  	spi_recv_data_in_word(spi, rx_buf + 2, len + 2);
5271  
5272  	for(i = 0; i < len + 2; i = i + 2)
5273  	{
5274  		tmp_buf[i + 0] = rx_buf[i + 1];
5275  		tmp_buf[i + 1] = rx_buf[i + 0];
5276  	}
5277  	crc1 = CRC16_2(tmp_buf, len + 2);
5278  	crc2 = (rx_buf[2 + len + 0] << 8) + (rx_buf[2 + len + 1] << 0);
5279  
5280  	if (crc1 != crc2) {
5281  		applog(LOG_WARNING, "%s crc error !", __FUNCTION__);
5282  		return false;
5283  	}
5284  
5285  	memcpy(out, rx_buf + 2, len);
5286  
5287  	return true;
5288  }
5289  
5290  
5291  bool spi_cmd_read_result(unsigned char chain_id, unsigned char chip_id, unsigned char *res, int len)
5292  {
5293  	int i;
5294  	int max_len;
5295  	unsigned short crc1, crc2;
5296  	ZYNQ_SPI_T *spi = &s_spi[chain_id];
5297  	unsigned char tx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5298  	unsigned char rx_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5299  	unsigned char tmp_buf[MCOMPAT_CONFIG_MAX_CMD_LENGTH];
5300  
5301  	applog(LOG_DEBUG, "%s,%d: %s ", __FILE__, __LINE__, __FUNCTION__);
5302  
5303  	if (res == NULL)
5304  	{
5305  		applog(LOG_ERR, "%s para error !", __FUNCTION__);
5306  		return false;
5307  	}
5308  
5309  	memset(tx_buf, 0, sizeof(tx_buf));
5310  	if (!spi_send_command(spi, CMD_READ_RESULT, chip_id, tx_buf, 2))
5311  	{
5312  		applog(LOG_WARNING, "%s send fail !", __FUNCTION__);
5313  		return false;
5314  	}
5315  
5316  	max_len = g_chip_num * 4;
5317  	memset(rx_buf, 0, sizeof(rx_buf));
5318  
5319  	for(i = 0; i < max_len; i = i + 2)
5320  	{
5321  		spi_recv_data(spi, rx_buf, 2);
5322  		if (((rx_buf[0] & 0x0f) == CMD_READ_RESULT) && (rx_buf[1] != 0))
5323  		{
5324  			break;
5325  		}
5326  	}
5327  
5328  	if (i >= max_len)
5329  	{
5330  		return false;
5331  	}
5332  
5333  	spi_recv_data_in_word(spi, rx_buf + 2, len + 2);
5334  
5335  	for(i = 0; i < len + 2; i = i + 2)
5336  	{
5337  		tmp_buf[i + 0] = rx_buf[i + 1];
5338  		tmp_buf[i + 1] = rx_buf[i + 0];
5339  	}
5340  	crc1 = CRC16_2(tmp_buf, len + 2);
5341  	crc2 = (rx_buf[2 + len + 0] << 8) + (rx_buf[2 + len + 1] << 0);
5342  
5343  	if (crc1 != crc2) {
5344  		applog(LOG_WARNING, "%s crc error !", __FUNCTION__);
5345  		return false;
5346  	}
5347  
5348  	memcpy(res, rx_buf, len + 2);
5349  
5350  	return true;
5351  }
5352  
5353  
5354  bool spi_cmd_write_job(unsigned char chain_id, unsigned char chip_id, unsigned char *job, int len)
5355  {
5356  	ZYNQ_SPI_T *spi = &s_spi[chain_id];
5357  
5358  	applog(LOG_DEBUG, "%s,%d: %s(%d, %d, %p, %d)", __FILE__, __LINE__, __FUNCTION__, chain_id, chip_id, job, len);
5359  
5360  	if (job == NULL)
5361  	{
5362  		applog(LOG_ERR, "%s para error !", __FUNCTION__);
5363  		return false;
5364  	}
5365  
5366  	spi_send_data(spi, job, len);
5367  
5368  	return true;
5369  }
5370  
5371  const unsigned short wCRCTalbeAbs[] =
5372  {
5373  	0x0000, 0xCC01, 0xD801, 0x1400,
5374  	0xF001, 0x3C00, 0x2800, 0xE401,
5375  	0xA001, 0x6C00, 0x7800, 0xB401,
5376  	0x5000, 0x9C01, 0x8801, 0x4400,
5377  };
5378  
5379  unsigned short CRC16_2(unsigned char* pchMsg, unsigned short wDataLen)
5380  {
5381  	volatile unsigned short wCRC = 0xFFFF;
5382  	unsigned short i;
5383  	unsigned char chChar;
5384  
5385  	for (i = 0; i < wDataLen; i++)
5386  	{
5387  		chChar = *pchMsg++;
5388  		wCRC = wCRCTalbeAbs[(chChar ^ wCRC) & 15] ^ (wCRC >> 4);
5389  		wCRC = wCRCTalbeAbs[((chChar >> 4) ^ wCRC) & 15] ^ (wCRC >> 4);
5390  	}
5391  
5392  	return wCRC;
5393  }
5394  
5395  
5396  void print_data_hex(char *arg, unsigned char *buff, int len)
5397  {
5398  	int i = 0;
5399  
5400  	printf("%s ", arg);
5401  	for(i = 0; i < len; i++)
5402  	{
5403  		printf("0x%02x ", buff[i]);
5404  		if ((i % 16) == 15)
5405  		{
5406  			//printf("");
5407  		}
5408  	}
5409  
5410  	if ((len % 16) != 0)
5411  	{
5412  		//printf("");
5413  	}
5414  }
5415  
5416  unsigned int SUNXI_IO_BASE = 0;
5417  
5418  /*******************************************************************************************
5419   * GPIO
5420   *******************************************************************************************/
5421  int gpio_init(void)
5422  {
5423  	int fd;
5424  	unsigned int addr_start, addr_offset, PageSize, PageMask;
5425  	void *pc;
5426  
5427  	fd = open("/dev/mem", O_RDWR);
5428  	if (fd < 0)
5429  		return -1;
5430  
5431  	PageSize = sysconf(_SC_PAGESIZE);
5432  	PageMask = (~(PageSize - 1));
5433  
5434  	addr_start = SW_PORTC_IO_BASE & PageMask;
5435  	addr_offset = SW_PORTC_IO_BASE & ~PageMask;
5436  
5437  	pc = (void *)mmap(0, PageSize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr_start);
5438  
5439  	if (pc == MAP_FAILED)
5440  		return -1;
5441  
5442  	SUNXI_IO_BASE = (unsigned int) pc;
5443  	SUNXI_IO_BASE += addr_offset;
5444  
5445  	close(fd);
5446  	return 0;
5447  }
5448  
5449  int gpio_setcfg(unsigned int pin, unsigned int p1)
5450  {
5451  	unsigned int cfg;
5452  	unsigned int bank = GPIO_BANK(pin);
5453  	unsigned int index = GPIO_CFG_INDEX(pin);
5454  	unsigned int offset = GPIO_CFG_OFFSET(pin);
5455  
5456  	if (SUNXI_IO_BASE == 0)
5457  		return -1;
5458  
5459  	struct sunxi_gpio *pio = &((struct sunxi_gpio_reg *) SUNXI_IO_BASE)->gpio_bank[bank];
5460  
5461  	cfg = *(&pio->cfg[0] + index);
5462  	cfg &= ~(0xf << offset);
5463  	cfg |= p1 << offset;
5464  
5465  	*(&pio->cfg[0] + index) = cfg;
5466  
5467  	return 0;
5468  }
5469  
5470  int gpio_getcfg(unsigned int pin)
5471  {
5472  	unsigned int cfg;
5473  	unsigned int bank = GPIO_BANK(pin);
5474  	unsigned int index = GPIO_CFG_INDEX(pin);
5475  	unsigned int offset = GPIO_CFG_OFFSET(pin);
5476  
5477  	if (SUNXI_IO_BASE == 0)
5478  		return -0;
5479  
5480  	struct sunxi_gpio *pio = &((struct sunxi_gpio_reg *) SUNXI_IO_BASE)->gpio_bank[bank];
5481  	cfg = *(&pio->cfg[0] + index);
5482  	cfg >>= offset;
5483  
5484  	return (cfg & 0xf);
5485  }
5486  
5487  int gpio_output(unsigned int pin, unsigned int p1)
5488  {
5489  	unsigned int bank = GPIO_BANK(pin);
5490  	unsigned int num = GPIO_NUM(pin);
5491  
5492  	if (SUNXI_IO_BASE == 0)
5493  		return -1;
5494  
5495  	struct sunxi_gpio *pio = &((struct sunxi_gpio_reg *) SUNXI_IO_BASE)->gpio_bank[bank];
5496  
5497  	if (p1)
5498  		*(&pio->dat) |= 1 << num;
5499  	else
5500  		*(&pio->dat) &= ~(1 << num);
5501  
5502  	return 0;
5503  }
5504  
5505  int gpio_pullup(unsigned int pin, unsigned int p1)
5506  {
5507  	unsigned int cfg;
5508  	unsigned int bank = GPIO_BANK(pin);
5509  	unsigned int index = GPIO_PUL_INDEX(pin);
5510  	unsigned int offset = GPIO_PUL_OFFSET(pin);
5511  
5512  	if (SUNXI_IO_BASE == 0)
5513  		return -1;
5514  
5515  	struct sunxi_gpio *pio = &((struct sunxi_gpio_reg *) SUNXI_IO_BASE)->gpio_bank[bank];
5516  
5517  	cfg = *(&pio->pull[0] + index);
5518  	cfg &= ~(0x3 << offset);
5519  	cfg |= p1 << offset;
5520  
5521  	*(&pio->pull[0] + index) = cfg;
5522  
5523  	return 0;
5524  }
5525  
5526  int gpio_input(unsigned int pin)
5527  {
5528  	unsigned int dat;
5529  	unsigned int bank = GPIO_BANK(pin);
5530  	unsigned int num = GPIO_NUM(pin);
5531  
5532  	if (SUNXI_IO_BASE == 0)
5533  		return -1;
5534  
5535  	struct sunxi_gpio *pio = &((struct sunxi_gpio_reg *) SUNXI_IO_BASE)->gpio_bank[bank];
5536  
5537  	dat = *(&pio->dat);
5538  	dat >>= num;
5539  
5540  	return (dat & 0x1);
5541  }
5542  
5543  /*******************************************************************************************
5544   * I2C
5545   *******************************************************************************************/
5546  int i2c_open(char *dev, uint8_t address)
5547  {
5548  	int fd;
5549  	int ret;
5550  
5551  	fd = open(dev, O_RDWR);
5552  	if (fd < 0)
5553  		return fd;
5554  
5555  	ret = ioctl(fd, I2C_SLAVE_FORCE, address);
5556  	if (ret < 0)
5557  		return ret;
5558  
5559  	return fd;
5560  }
5561  
5562  int i2c_close(int fd)
5563  {
5564  	return (close(fd));
5565  }
5566  
5567  int i2c_send(int fd, uint8_t *buf, uint8_t num_bytes)
5568  {
5569  	return (write(fd, buf, num_bytes));
5570  }
5571  
5572  int i2c_read(int fd, uint8_t *buf, uint8_t num_bytes)
5573  {
5574  	return (write(fd, buf, num_bytes));
5575  }
5576  
5577  /*******************************************************************************************
5578   * spi
5579   *******************************************************************************************/
5580  int spi_open(char *dev, spi_config_t config)
5581  {
5582  	int fd;
5583  
5584  	fd = open(dev, O_RDWR);
5585  	if (fd < 0)
5586  		return fd;
5587  
5588  	/* Set SPI_POL and SPI_PHA */
5589  	if (ioctl(fd, SPI_IOC_WR_MODE, &config.mode) < 0)
5590  		return -1;
5591  
5592  	if (ioctl(fd, SPI_IOC_RD_MODE, &config.mode) < 0)
5593  		return -1;
5594  
5595  	/* Set bits per word*/
5596  	if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &config.bits) < 0)
5597  		return -1;
5598  
5599  	if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &config.bits) < 0)
5600  		return -1;
5601  
5602  	/* Set SPI speed*/
5603  	if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &config.speed) < 0)
5604  		return -1;
5605  
5606  	if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &config.speed) < 0)
5607  		return -1;
5608  
5609  	return fd;
5610  }
5611  
5612  int spi_close(int fd)
5613  {
5614  	return (close(fd));
5615  }
5616  
5617  int spi_xfer(int fd, uint8_t *tx_buf, uint8_t tx_len, uint8_t *rx_buf, uint8_t rx_len)
5618  {
5619  	struct spi_ioc_transfer spi_message[2];
5620  
5621  	memset(spi_message, 0, sizeof(spi_message));
5622  
5623  	spi_message[0].rx_buf = (unsigned long)tx_buf;
5624  	spi_message[0].len = tx_len;
5625  
5626  	spi_message[1].tx_buf = (unsigned long)rx_buf;
5627  	spi_message[1].len = rx_len;
5628  
5629  	return ioctl(fd, SPI_IOC_MESSAGE(2), spi_message);
5630  }
5631  
5632  int spi_read(int fd, uint8_t *rx_buf, uint8_t rx_len)
5633  {
5634  	struct spi_ioc_transfer spi_message[1];
5635  	memset(spi_message, 0, sizeof(spi_message));
5636  
5637  	spi_message[0].rx_buf = (unsigned long)rx_buf;
5638  	spi_message[0].len = rx_len;
5639  
5640  	return ioctl(fd, SPI_IOC_MESSAGE(1), spi_message);
5641  }
5642  
5643  int spi_write(int fd, uint8_t *tx_buffer, uint8_t tx_len)
5644  {
5645  	struct spi_ioc_transfer spi_message[1];
5646  	memset(spi_message, 0, sizeof(spi_message));
5647  
5648  	spi_message[0].tx_buf = (unsigned long)tx_buffer;
5649  	spi_message[0].len = tx_len;
5650  
5651  	return ioctl(fd, SPI_IOC_MESSAGE(1), spi_message);
5652  }
5653  
5654  /*******************************************************************************************
5655   * time
5656   *******************************************************************************************/
5657  void delay(unsigned int howLong)
5658  {
5659  	struct timespec sleeper, dummy ;
5660  
5661  	sleeper.tv_sec  = (time_t)(howLong / 1000) ;
5662  	sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
5663  
5664  	nanosleep (&sleeper, &dummy) ;
5665  }
5666  
5667  static int opi_spi_fd = 0;
5668  static pthread_mutex_t opi_spi_lock;
5669  static struct spi_config opi_spi_config = {
5670  	.bus		= DEFAULT_SPI_BUS,
5671  	.cs_line	= DEFAULT_SPI_CS_LINE,
5672  	.mode		= DEFAULT_SPI_MODE,
5673  	.speed		= DEFAULT_SPI_SPEED,
5674  	.bits		= DEFAULT_SPI_BITS_PER_WORD,
5675  	.delay		= DEFAULT_SPI_DELAY_USECS,
5676  };
5677  
5678  
5679  void opi_spi_gpio_init(void)
5680  {
5681  	if (gpio_init() == -1) {
5682  		printf("gpio initial fail");
5683  	}
5684  
5685  	gpio_setcfg(PIN_SPI_E1, OUTPUT);
5686  	gpio_output(PIN_SPI_E1, HIGH);
5687  
5688  	gpio_setcfg(PIN_SPI_A0, OUTPUT);
5689  	gpio_output(PIN_SPI_A0, HIGH);
5690  	gpio_setcfg(PIN_SPI_A1, OUTPUT);
5691  	gpio_output(PIN_SPI_A1, HIGH);
5692  	gpio_setcfg(PIN_SPI_A2, OUTPUT);
5693  	gpio_output(PIN_SPI_A2, HIGH);
5694  }
5695  
5696  void opi_spi_cs_enable(int id)
5697  {
5698  	if (id & 01)
5699  	{
5700  		gpio_output(PIN_SPI_A0, HIGH);
5701  	}
5702  	else
5703  	{
5704  		gpio_output(PIN_SPI_A0, LOW);
5705  	}
5706  
5707  	if (id & 02)
5708  	{
5709  		gpio_output(PIN_SPI_A1, HIGH);
5710  	}
5711  	else
5712  	{
5713  		gpio_output(PIN_SPI_A1, LOW);
5714  	}
5715  
5716  	if (id & 04)
5717  	{
5718  		gpio_output(PIN_SPI_A2, HIGH);
5719  	}
5720  	else
5721  	{
5722  		gpio_output(PIN_SPI_A2, LOW);
5723  	}
5724  
5725  	gpio_output(PIN_SPI_E1, LOW);
5726  }
5727  
5728  void opi_spi_cs_disable(void)
5729  {
5730  	gpio_output(PIN_SPI_E1, HIGH);
5731  }
5732  
5733  void opi_spi_init(void)
5734  {
5735  	char dev_fname[PATH_MAX];
5736  	struct spi_config *config = &opi_spi_config;
5737  
5738  	pthread_mutex_init(&opi_spi_lock, NULL);
5739  	opi_spi_gpio_init();
5740  
5741  	sprintf(dev_fname, SPI_DEVICE_TEMPLATE, config->bus, config->cs_line);
5742  
5743  	int fd = open(dev_fname, O_RDWR);
5744  	if (fd < 0) {
5745  		applog(LOG_ERR, "SPI: Can not open SPI device %s ", dev_fname);
5746  	}
5747  
5748  	if ((ioctl(fd, SPI_IOC_WR_MODE, &config->mode) < 0) ||
5749  		(ioctl(fd, SPI_IOC_RD_MODE, &config->mode) < 0) ||
5750  		(ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &config->bits) < 0) ||
5751  		(ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &config->bits) < 0) ||
5752  		(ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &config->speed) < 0) ||
5753  		(ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &config->speed) < 0)) {
5754  		close(fd);
5755  	applog(LOG_ERR, "SPI: ioctl error on SPI device %s", dev_fname);
5756  		}
5757  
5758  		opi_spi_fd = fd;
5759  
5760  		applog(LOG_INFO, "SPI '%s': mode=%hhu, bits=%hhu, speed=%u ", dev_fname, config->mode, config->bits, config->speed);
5761  }
5762  
5763  void opi_spi_exit(void)
5764  {	
5765  	close(opi_spi_fd);
5766  }
5767  
5768  /*
5769   * void opi_set_spi_speed(uint32_t speed)
5770   * {
5771   * pthread_mutex_lock(&opi_spi_lock);
5772   *
5773   * if ((ioctl(opi_spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, speed) < 0) ||
5774   * (ioctl(opi_spi_fd, SPI_IOC_RD_MAX_SPEED_HZ, speed) < 0)) {
5775   * applog(LOG_ERR, "SPI: ioctl error on SPI device");
5776   * }
5777   *
5778   * opi_spi_config.speed = speed;
5779   *
5780   * pthread_mutex_unlock(&opi_spi_lock);
5781   * }
5782   */
5783  bool opi_spi_transfer(uint8_t id, uint16_t *txbuf, uint16_t *rxbuf, int len)
5784  {
5785  	struct spi_ioc_transfer xfr;
5786  	int ret;
5787  
5788  	if (rxbuf != NULL) {
5789  		memset(rxbuf, 0xff, len);
5790  	}
5791  
5792  	pthread_mutex_lock(&opi_spi_lock);
5793  
5794  	opi_spi_cs_enable(id);
5795  	cgsleep_ms(1); // usleep(1);
5796  
5797  	ret = len;
5798  
5799  	xfr.tx_buf = (unsigned long)txbuf;
5800  	xfr.rx_buf = (unsigned long)rxbuf;
5801  	xfr.len = len;
5802  	xfr.speed_hz = opi_spi_config.speed;
5803  	xfr.delay_usecs = opi_spi_config.delay;
5804  	xfr.bits_per_word = opi_spi_config.bits;
5805  	xfr.cs_change = 0;
5806  	xfr.pad = 0;
5807  
5808  	ret = ioctl(opi_spi_fd, SPI_IOC_MESSAGE(1), &xfr);
5809  	if (ret < 1) {
5810  		applog(LOG_ERR, "SPI: ioctl error on SPI device: %d", ret);
5811  	}
5812  
5813  	cgsleep_ms(1); // usleep(1);
5814  	opi_spi_cs_disable();
5815  
5816  	pthread_mutex_unlock(&opi_spi_lock);
5817  
5818  	return ret > 0;
5819  }
5820  
5821  int g_platform;
5822  int g_miner_type;
5823  int g_chain_num;
5824  int g_chip_num;
5825  
5826  
5827  bool sys_platform_init(int platform, int miner_type, int chain_num, int chip_num)
5828  {
5829  	applog(LOG_NOTICE, "sys : platform[%d] miner_type[%d] chain_num[%d] chip_num[%d] ", platform, miner_type, chain_num, chip_num);
5830  
5831  	switch(platform)
5832  	{
5833  		case PLATFORM_ZYNQ_SPI_G9:
5834  		case PLATFORM_ZYNQ_SPI_G19:
5835  		case PLATFORM_ZYNQ_HUB_G9:
5836  		case PLATFORM_ZYNQ_HUB_G19:
5837  		case PLATFORM_SOC:
5838  			break;
5839  		default:
5840  			applog(LOG_ERR, "the platform is undefined !!! ");
5841  			break;
5842  	}
5843  
5844  	if (chain_num > MCOMPAT_CONFIG_MAX_CHAIN_NUM)
5845  	{
5846  		applog(LOG_ERR, "the chain_num is error !!! ");
5847  		return false;
5848  	}
5849  
5850  	if (chip_num > MCOMPAT_CONFIG_MAX_CHIP_NUM)
5851  	{
5852  		applog(LOG_ERR, "the chip_num is error !!! ");
5853  		return false;
5854  	}
5855  
5856  	g_platform = platform;
5857  	g_miner_type = miner_type;
5858  	g_chain_num = chain_num;
5859  	g_chip_num = chip_num;
5860  
5861  	init_mcompat_cmd();
5862  
5863  	init_mcompat_gpio();
5864  
5865  	init_mcompat_pwm();
5866  
5867  	init_mcompat_chain();
5868  
5869  	return true;
5870  }
5871  
5872  
5873  bool sys_platform_exit(void)
5874  {
5875  	exit_mcompat_cmd();
5876  
5877  	exit_mcompat_gpio();
5878  
5879  	exit_mcompat_pwm();
5880  
5881  	exit_mcompat_chain();
5882  
5883  	return true;
5884  }
5885