三 s5p4418对mcp2515 can总线的支持

对于mcp2515的移植相关知识课先参考这里http://blog.csdn.net/sno_guo/article/details/17029295


下面是针对s5p4418官方提供的内核为基础做的相关修改。

对于2515的驱动我们不用关心,直接使用内核自带的即可。首先我们需要对内核的配置做添加,具体如下面的图所示:

三 s5p4418对mcp2515 can总线的支持_第1张图片

三 s5p4418对mcp2515 can总线的支持_第2张图片

三 s5p4418对mcp2515 can总线的支持_第3张图片

务必确保内核的配置中上面图片的选择是被打开的,免得做其他工作时造成未知的问题。


下面是修改板级目录下device.c的文件,找到下面的代码,并修改成如下所示:

/*------------------------------------------------------------------------------
 * SSP/SPI
 */
#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
#include <linux/spi/spi.h>
#include <linux/can/platform/mcp251x.h>
static void spi0_cs(u32 chipselect)
{
	//printk("ERTER:%s ......\n",__func__);
#if (CFG_SPI0_CS_GPIO_MODE)
	if(nxp_soc_gpio_get_io_func( CFG_SPI0_CS )!= nxp_soc_gpio_get_altnum( CFG_SPI0_CS))
		nxp_soc_gpio_set_io_func( CFG_SPI0_CS, nxp_soc_gpio_get_altnum( CFG_SPI0_CS));

	nxp_soc_gpio_set_io_dir( CFG_SPI0_CS,1);
	nxp_soc_gpio_set_out_value(	CFG_SPI0_CS , chipselect);
#else
	;
#endif
}
struct pl022_config_chip spi0_info = {
    /* available POLLING_TRANSFER, INTERRUPT_TRANSFER, DMA_TRANSFER */
    .com_mode = CFG_SPI0_COM_MODE,
    .iface = SSP_INTERFACE_MOTOROLA_SPI,
    /* We can only act as master but SSP_SLAVE is possible in theory */
    .hierarchy = SSP_MASTER,
    /* 0 = drive TX even as slave, 1 = do not drive TX as slave */
    .slave_tx_disable = 1, 
    .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM,
    .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC,
    .ctrl_len = SSP_BITS_8,
    .wait_state = SSP_MWIRE_WAIT_ZERO,
    .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
    /*
     * This is where you insert a call to a function to enable CS
     * (usually GPIO) for a certain chip.
     */
#if (CFG_SPI0_CS_GPIO_MODE)
    .cs_control = spi0_cs,
#endif
	.clkdelay = SSP_FEEDBACK_CLK_DELAY_1T,

};
void s5p4418_mcp2515_init(void)
{
	printk("ERTER:%s ......\n",__func__);
	nxp_soc_gpio_set_io_func(PAD_GPIO_C+ 30, 0); 
    nxp_soc_gpio_set_io_func(PAD_GPIO_C+ 29, 1); 
    nxp_soc_gpio_set_io_func(PAD_GPIO_D+ 0,  1); 
    nxp_soc_gpio_set_io_func(PAD_GPIO_C+ 31, 1); 
    nxp_soc_gpio_set_io_func(PAD_GPIO_B+ 6,  0); 	
}
static struct mcp251x_platform_data mcp251x_info = {
                     .oscillator_frequency = 20 * 1000 * 1000,
                     .board_specific_setup = &s5p4418_mcp2515_init,
                     .power_enable = NULL,
                     .transceiver_enable = NULL,
};
static struct spi_board_info spi_plat_board[] __initdata = {
#ifdef CONFIG_CAN_MCP251X
	[0] = {
        .modalias        = "mcp2515",    /* fixup */
        .max_speed_hz    = 1 * 1000 * 1000,     /* max spi clock (SCK) speed in HZ */
        .bus_num         = 0,           /* Note> set bus num, must be smaller than ARRAY_SIZE(spi_plat_device) */
        .chip_select     = 0,           /* Note> set chip select num, must be smaller than spi cs_num */
        .controller_data = &spi0_info,
        .mode            = SPI_MODE_0,
        .platform_data   = &mcp251x_info,
        .irq             = PB_PIO_IRQ(CFG_IO_CAN_DETECT),
    },
#else
    [0] = {
        .modalias        = "spidev",    /* fixup */
        .max_speed_hz    = 3125000,     /* max spi clock (SCK) speed in HZ */
        .bus_num         = 0,           /* Note> set bus num, must be smaller than ARRAY_SIZE(spi_plat_device) */
        .chip_select     = 0,           /* Note> set chip select num, must be smaller than spi cs_num */
        .controller_data = &spi0_info,
        .mode            = SPI_MODE_3 | SPI_CPOL | SPI_CPHA,
    },
#endif
};

#endif

相对于源码主要做的修改是:

1.spi_plat_board结构体增加了对mcp2515的定义

2.添加mcp251x_info结构定义

3.添加void s5p4418_mcp2515_init(void)函数

这里说明一下void s5p4418_mcp2515_init(void)函数的意义,该函数是对SPI0的GPIO做了配置,在默认的情况下SPI0的GPIO不一定为SPI的功能,所以这里务必需要重新配置一下(由于开始没注意,导致了无法初始化的问题),当然这个配置工作也可以在其他的地方做。


CFG_IO_CAN_DETECT这个定义是在板级目录的include目录下cfg_main.h文件中,这里定义的是GPIOB6引脚。


做了上面的配置之后初始化就应该没有问题了。

使用ifconfig can0 up进行检测,如果不报错那么与mcp2515的通信是没有问题了。

剩下的就可以使用ip、candump等命令进行 can操作了。

希望对移植can遇到问题的朋友有所帮助。

你可能感兴趣的:(内核,can,mmcp2515)