I have a customer who needs assistance getting Multiple SPI ports to function on the latest Version of the TI DVSDK. There are three C Files that I could forward but I cannot attach then to the post.
I had applied the patches for multiple SPI support on previous DVSDK_omapl138-evm_4_02_00_06 with linux-2.6.33 and everything was working perfectly for us by pulling the most current SPI source code of linux-2.6.35 from kernel.org and merged it into linux-2.6.33 and added custom logic for Chip Select to implement GPIO inside davinci_spi_chipselect function (davinci_spi.c). Now I migrated our BSP to TI most current DVSDK and I have been having troubled to get multiple SPI support to work; have seen multiple devices (spi1.0 for mtd m25p as it supposed to but no DMA transfer to LCD with the davinci_spi.c-newkernel unless I use the old davinic_spi.c and davinic_spi.h). If I keep every new SPI source intact and only move davinci_spi.c from old BSP over, everything seems to work just fine but I really like to keep all the SPI source sync with your current davinci_spi.c for future patch if possible. I think the difference is in DMA section inside davinci_spi.c file and I don’t know about DMA enough to feel comfortable to modify it. Please refer to attached files to identify the differences if desired. The following function is the main "Customer" custom logic, please advice how to get this logic work with your current linux-2.6.37/driver/spi/davinci_spi.c.
static void davinci_spi_chipselect(struct spi_device *spi, int value)
{
struct davinci_spi *dspi;
struct davinci_spi_platform_data *pdata;
struct davinci_spi_config *spicfg;
u8 chip_sel = spi->chip_select;
u16 spidat1 = CS_DEFAULT;
//u16 spidat1_cfg;
int i;
dspi = spi_master_get_devdata(spi->master);
pdata = dspi->pdata;
spicfg = (struct davinci_spi_config *)spi->controller_data;
//printk("spi_addr %d chip_sel %d\n", spicfg->spi_addr, chip_sel);
for(i = 0; i < pdata->num_chipselect; i++)
{
if (pdata->chip_sel[i] == SPI_INTERN_CS)
{
if ((i == chip_sel) && (value == BITBANG_CS_ACTIVE))
{
spidat1 |= SPIDAT1_CSHOLD_MASK;
spidat1 &= ~(0x1 << chip_sel);
printk("\n%s:BITBANG_CS_ACTIVE&INTERN %d\n", __func__, pdata->chip_sel[i]);
}
}
else if (pdata->chip_sel[i] == DA850_SPI_LCD_CS) // JVM added for SPI A0 workaround
{
if (value == BITBANG_CS_INACTIVE)
{
gpio_set_value(pdata->chip_sel[i], 1);
//printk("\n%s:BITBANG_CS_HIGH %d\n", __func__, pdata->chip_sel[i]);
}
else if (pdata->chip_sel[chip_sel] == DA850_SPI_LCD_CS)
{
gpio_set_value(DA850_SPI_LCD_CS, 0);
if ( spicfg->spi_addr == 0 )
{
gpio_set_value(DA850_SPI_LCD_CMD_DATA, 0);
//printk("\n%s:BITBANG_CS_LOW CMD %d\n", __func__, pdata->chip_sel[i]);
}
else
{
gpio_set_value(DA850_SPI_LCD_CMD_DATA, 1);
//printk("\n%s:BITBANG_CS_LOW DATA %d\n", __func__, pdata->chip_sel[i]);
}
}
}
else
{
if (value == BITBANG_CS_INACTIVE)
{
gpio_set_value(pdata->chip_sel[i], 1);
printk("\n%s:BITBANG_CS_HIGH OTHERS %d\n", __func__, pdata->chip_sel[i]);
}
else if (i == chip_sel) {
gpio_set_value(pdata->chip_sel[i], 0);
printk("\n%s:BITBANG_CS_LOW OTHERS %d\n", __func__, pdata->chip_sel[i]);
}
}
}
iowrite16(spidat1, dspi->base + SPIDAT1 + 2);
}