/**
 * @note Copyright (c) 2006  Sagem Communication All rights reserved
 *
 * @file sbi_utils.c
 * @version 1.0
 * @date 25/11/2006
 * @author Sagem Communication
 * @brief 
**/

#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

#include <linux/sbi_k.h>
#include <main/sbi_u.h>
#include <linux/sbi_ioctl.h>

int sbi_ioctl(struct inode *inode, struct file *file,
              unsigned int cmd, unsigned long arg);

/* Driver file operations */
struct file_operations sbi_fops = {
                        ioctl:sbi_ioctl
};

/****************************************************************
 *  Function Name : sbi_driver_init.                            *
 *  Description   : SBI Module Init Function.                   *
 *  Input         : None.                                       *
 *  Output        : None.                                       *
 *  Return Value  : None.                                       *
 ***************************************************************/
int sbi_driver_init(void)
{
  int result;
  result = register_chrdev(SBI_MAJOR, SBI_DEVICE,&sbi_fops);
  if(result != 0)
  {
    printk("Could not register the character sbi device \n");
    return -1;
  }
  return 0;
}

/****************************************************************
 *  Function Name : sbi_driver_exit.                            *
 *  Description   : SBI Module exit Function.                   *
 *  Input         : None.                                       *
 *  Output        : None.                                       *
 *  Return Value  : None.                                       *
 ***************************************************************/
void sbi_driver_exit(void)
{
  unregister_chrdev(SBI_MAJOR, SBI_DEVICE);
}

/****************************************************************
 *  Function Name : sbi_ioctl.                                  *
 *  Description   : SBI Module ioctl Function.                  *
 *  Output        : Output data, if any                         *
 *  Return Value  : Number of bytes read.                       *
 ***************************************************************/
int sbi_ioctl(struct inode *inode, struct file *file,
              unsigned int cmd, unsigned long arg)
{
  int Bytes_left = 0;
  static struct user_board_info tSbi ;
  static struct interrupt_numbers tInt_nums ;
    
  switch(cmd)
  {
    case READ_SBI:
      /* Update tsbi */
      strncpy(tSbi.board_name, sbi->board_name, sizeof(tSbi.board_name));
      tSbi.cpu_id                    = sbi->cpu_id;
      tSbi.vendor_id                 = sbi->vendor_id;
      tSbi.ram_ctrl_addr             = NULL;
      tSbi.sdram_size                = sbi->sdram_size;
      tSbi.sdram_size_with_rg_loader = sbi->sdram_size_with_rg_loader;
      tSbi.flash_size                = sbi->flash_size;
      tSbi.mtd_partition_jffs2_offset= sbi->mtd_partition_jffs2_offset;
      tSbi.mtd_partition_jffs2_size  = sbi->mtd_partition_jffs2_size;
      tSbi.int_nums                  = NULL; //update in init_sbi_ioctl.c after READ_INT
      tSbi.first_pci_pin             = sbi->first_pci_pin;

      Bytes_left = copy_to_user((void *)arg, &tSbi, sizeof(tSbi));
      return (Bytes_left);

    case READ_INT:
      /* Update tInt_nums  */
      tInt_nums.adi_6843_max_ints = sbi->int_nums->adi_6843_max_ints;
      tInt_nums.ap_dma_int        = sbi->int_nums->ap_dma_int;
      tInt_nums.arb2_int          = sbi->int_nums->arb2_int;
      tInt_nums.arb3_int          = sbi->int_nums->arb3_int;
      tInt_nums.arb_int           = sbi->int_nums->arb_int;
      tInt_nums.bmu_int           = sbi->int_nums->bmu_int;
      tInt_nums.dma_int           = sbi->int_nums->dma_int;
      tInt_nums.dsp0_fl0_int      = sbi->int_nums->dsp0_fl0_int;
      tInt_nums.dsp0_fl1_int      = sbi->int_nums->dsp0_fl1_int;
      tInt_nums.dsp0_pf0_int      = sbi->int_nums->dsp0_pf0_int;
      tInt_nums.dsp0_pf1_int      = sbi->int_nums->dsp0_pf1_int;
      tInt_nums.dsp1_fl0_int      = sbi->int_nums->dsp1_fl0_int;
      tInt_nums.dsp1_fl1_int      = sbi->int_nums->dsp1_fl1_int;
      tInt_nums.dsp1_pf0_int      = sbi->int_nums->dsp1_pf0_int;
      tInt_nums.dsp1_pf1_int      = sbi->int_nums->dsp1_pf1_int;
      tInt_nums.emac1_int         = sbi->int_nums->emac1_int;
      tInt_nums.emac2_int         = sbi->int_nums->emac2_int;
      tInt_nums.emac3_int         = sbi->int_nums->emac3_int;
      tInt_nums.gpio2_int         = sbi->int_nums->gpio2_int;
      tInt_nums.gpio_int          = sbi->int_nums->gpio_int;
      tInt_nums.gpt1_int          = sbi->int_nums->gpt1_int;
      tInt_nums.gpt2_int          = sbi->int_nums->gpt2_int;
      tInt_nums.gpt3_int          = sbi->int_nums->gpt3_int;
      tInt_nums.idma1_int         = sbi->int_nums->idma1_int;
      tInt_nums.idma2_int         = sbi->int_nums->idma2_int;
      tInt_nums.idma3_int         = sbi->int_nums->idma3_int;
      tInt_nums.pci_int           = sbi->int_nums->pci_int;
      tInt_nums.per_int           = sbi->int_nums->per_int;
      tInt_nums.scu_int           = sbi->int_nums->scu_int;
      tInt_nums.spa_int           = sbi->int_nums->spa_int;
      tInt_nums.sphy_int          = sbi->int_nums->sphy_int;
      tInt_nums.spi_int           = sbi->int_nums->spi_int;
      tInt_nums.sport2_rx_int     = sbi->int_nums->sport2_rx_int;
      tInt_nums.sport2_tx_int     = sbi->int_nums->sport2_tx_int;
      tInt_nums.uart1_int         = sbi->int_nums->uart1_int;
      tInt_nums.uart2             = sbi->int_nums->uart2;
      tInt_nums.uart2_int         = sbi->int_nums->uart2_int;
      tInt_nums.usbh_int          = sbi->int_nums->usbh_int;
      tInt_nums.usb_int           = sbi->int_nums->usb_int;
      tInt_nums.wiu1_int          = sbi->int_nums->wiu1_int;
      tInt_nums.wiu2_int          = sbi->int_nums->wiu2_int;

      Bytes_left = copy_to_user((void *)arg,&tInt_nums,sizeof(tInt_nums));
      return (Bytes_left);

   default:
      printk("%s Unknown IOCTL Command %u \n",__FUNCTION__, cmd);
      return -1;
  }
  
  return 0 ; /* We don't have any thing to do with RTP application */
}

