/*
 * hal_drivers.c - Driver initializers for TSAR
 *
 * Copyright (c) 2017 Maxime Villard
 *
 * This file is part of ALMOS-MKH.
 *
 * ALMOS-MKH is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2.0 of the License.
 *
 * ALMOS-MKH is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <hal_types.h>
#include <chdev.h>
#include <hal_drivers.h>
#include <printk.h>

#include <soclib_tty.h>
#include <soclib_pic.h>
#include <soclib_iob.h>
#include <soclib_bdv.h>
#include <soclib_hba.h>
#include <soclib_mmc.h>
#include <soclib_nic.h>
#include <soclib_dma.h>

#include <dev_txt.h>
#include <dev_pic.h>
#include <dev_ioc.h>
#include <dev_mmc.h>
#include <dev_nic.h>
#include <dev_dma.h>

///////////////////////////////////////////////////////////////////////////////
//    TXT
///////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////
void hal_drivers_txt_init( chdev_t  * txt,
                           uint32_t   impl )
{
	if( impl == IMPL_TXT_TTY )
	{
		soclib_tty_init( txt );
	}
	else
	{
		assert( false , __FUNCTION__ , "undefined TXT device implementation" );
	}
}

///////////////////////////////////////////////////////////////////////////////
//    PIC
///////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////
void hal_drivers_pic_init( chdev_t  * pic,
                           uint32_t   impl )
{
    if( impl != IMPL_PIC_SCL )
    {
        assert( false , __FUNCTION__ , "undefined PIC device implementation" );
    }

	soclib_pic_init( pic );

	/* update the PIC chdev extension */
	pic->ext.pic.enable_timer = &soclib_pic_enable_timer;
	pic->ext.pic.enable_ipi   = &soclib_pic_enable_ipi;
	pic->ext.pic.enable_irq   = &soclib_pic_enable_irq;
	pic->ext.pic.disable_irq  = &soclib_pic_disable_irq;
	pic->ext.pic.bind_irq     = &soclib_pic_bind_irq;
	pic->ext.pic.send_ipi     = &soclib_pic_send_ipi;
	pic->ext.pic.extend_init  = &soclib_pic_extend_init;
}

///////////////////////////////////////////////////////////////////////////////
//    IOB
///////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////
void hal_drivers_iob_init( chdev_t  * iob,
                           uint32_t   impl )
{
	if (impl != IMPL_IOB_TSR) 
	{
		assert( false , __FUNCTION__ , "undefined IOB device implementation" );
	}

	soclib_iob_init( iob );

	/* update the IOB chdev extension */
	iob->ext.iob.set_active = &soclib_iob_set_active;
	iob->ext.iob.set_ptpr   = &soclib_iob_set_ptpr;
	iob->ext.iob.inval_page = &soclib_iob_inval_page;
	iob->ext.iob.get_bvar   = &soclib_iob_get_bvar;
	iob->ext.iob.get_srcid  = &soclib_iob_get_srcid;
	iob->ext.iob.get_error  = &soclib_iob_get_error;
}

///////////////////////////////////////////////////////////////////////////////
//    IOC
///////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////
void hal_drivers_ioc_init( chdev_t  * ioc,
                           uint32_t   impl )
{
	if (impl == IMPL_IOC_BDV) 
    {
		soclib_bdv_init( ioc );
	} 
    else if (impl == IMPL_IOC_HBA)
    {
		soclib_hba_init( ioc );
	}
    else 
    {
		assert( false , __FUNCTION__ , "undefined IOC device implementation" );
	}
}

///////////////////////////////////////////////////////////////////////////////
//    MMC
///////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////
void hal_drivers_mmc_init( chdev_t  * mmc,
                           uint32_t   impl )
{
    if( impl == IMPL_MMC_TSR )
    {
        soclib_mmc_init( mmc );
    }
    else
    {
        assert( false , __FUNCTION__ , "undefined MMC device implementation" );
    }
}

///////////////////////////////////////////////////////////////////////////////
//    NIC
///////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////
void hal_drivers_nic_init( chdev_t  * nic,
                           uint32_t   impl )
{
    if( impl == IMPL_NIC_SOC )
    {
        soclib_nic_init( nic );
    }
    else
    {
        assert( false , __FUNCTION__ , "undefined NIC device implementation" );
    }
}

///////////////////////////////////////////////////////////////////////////////
//    DMA
///////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////
void hal_drivers_dma_init( chdev_t  * dma,
                           uint32_t   impl )
{
    if( impl == IMPL_DMA_SCL )
    {
        soclib_dma_init( dma );
    }
    else
    {
        assert( false , __FUNCTION__ , "undefined DMA implementation" );
    }
}

