123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- #include <rtdevice.h>
- #include "gtypes.h"
- #include "gd_spi.h"
- #include "drv_ssi.h"
- #include "platform.h"
- /*---------------------------------------------------------------------------*/
- /* local defines */
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- /* local data types */
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- /* local data */
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- /* local functions */
- /*---------------------------------------------------------------------------*/
- static void *gk_get_spi_dev_pri_data(struct rt_spi_device *device)
- {
- return device->parent.user_data;
- }
- static rt_err_t gk_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
- {
- struct gk_spi_slave_info *spi_slave;
- struct gk_spi_controller *spi_control;
- GD_SPI_OPEN_PARAMS_S openParamsP;
- rt_uint32_t spi_hz;
- rt_int32_t ret;
- rt_uint8_t data_width = 8,polarity;
- if(!device || !configuration)
- {
- rt_kprintf("%s,%d,param wrong!\n",__FUNCTION__,__LINE__);
- return RT_ERROR;
- }
- spi_slave = (struct gk_spi_slave_info *)gk_get_spi_dev_pri_data(device);
- spi_control = spi_slave->control;
- rt_sem_take(&spi_control->xfer_lock, RT_WAITING_FOREVER);
- if(spi_slave->spihandle > 0)
- {
- GD_SPI_Close(&spi_slave->spihandle);
- spi_slave->spihandle = -1;
- }
- openParamsP.spi = spi_control->id;
- openParamsP.slave = spi_slave->id;
- openParamsP.csgpio = spi_slave->cs_pin;
- openParamsP.used_irq = 1;
- if (configuration->max_hz > GD_SPI_FREQ_81M)
- spi_hz = GD_SPI_FREQ_81M;
- else
- spi_hz = configuration->max_hz;
- openParamsP.baudrate = spi_hz;
- /* CPOL */
- if (configuration->mode & RT_SPI_CPOL && configuration->mode & RT_SPI_CPHA)
- {
- polarity = SPI_POLARITY_MODE3;
- }
- else if(configuration->mode & RT_SPI_CPOL && !configuration->mode & RT_SPI_CPHA)
- {
- polarity = SPI_POLARITY_MODE2;
- }
- else if(!configuration->mode & RT_SPI_CPOL && configuration->mode & RT_SPI_CPHA)
- {
- polarity = SPI_POLARITY_MODE1;
- }
- else
- polarity = SPI_POLARITY_MODE0;
- openParamsP.polarity = polarity;
- ret = GD_SPI_Open(&openParamsP,&(spi_slave->spihandle));
- if(ret != GD_OK)
- {
- rt_kprintf("GD_SPI_Open failed!\n");
- rt_sem_release(&spi_control->xfer_lock);
- return RT_ERROR;
- }
- /* data_width */
- if (configuration->data_width <= 8)
- {
- data_width = 8;
- }
- else if (configuration->data_width <= 16)
- {
- data_width = 16;
- }
- ret = GD_SPI_SetDatFormat(spi_slave->spihandle, data_width);;
- if(ret != GD_OK)
- {
- rt_kprintf("GD_SPI_SetDatFormat failed!\n");
- rt_sem_release(&spi_control->xfer_lock);
- return RT_ERROR;
- }
- rt_sem_release(&spi_control->xfer_lock);
- return RT_EOK;
- }
- static rt_uint32_t gk_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
- {
- struct gk_spi_slave_info *spi_slave;
- struct gk_spi_controller *spi_control;
- GERR ret = GD_OK;
- if(!device || !message)
- {
- rt_kprintf("%s,%d,param wrong!\n",__FUNCTION__,__LINE__);
- return 0;
- }
- spi_slave = (struct gk_spi_slave_info *)gk_get_spi_dev_pri_data(device);
- if(!spi_slave)
- {
- rt_kprintf("%s,%d,param wrong!\n",__FUNCTION__,__LINE__);
- return 0;
- }
- spi_control = spi_slave->control;
- if(spi_slave->spihandle < 0)
- {
- rt_kprintf("%s,%d,spi channel not configured!\n",__FUNCTION__,__LINE__);
- return 0;
- }
- if(!message)
- {
- rt_kprintf("%s,%d,params wrong!\n",__FUNCTION__,__LINE__);
- return 0;
- }
- rt_sem_take(&spi_control->xfer_lock, RT_WAITING_FOREVER);
- if(message->cs_take)
- GD_SPI_GetDevice(spi_slave->spihandle);
- if(message->recv_buf && message->send_buf)
- ret = GD_SPI_WriteThenReadBytes(spi_slave->spihandle,(rt_uint8_t *)message->send_buf,message->length,
- (rt_uint8_t *)message->recv_buf,message->length);
- else if(message->send_buf && !message->recv_buf)
- ret = GD_SPI_WriteBytes(spi_slave->spihandle,(rt_uint8_t *)message->send_buf,message->length);
- else if(!message->send_buf && message->recv_buf)
- ret = GD_SPI_WriteThenReadBytes(spi_slave->spihandle,NULL,0,(rt_uint8_t *)message->recv_buf,message->length);
- if(message->cs_release)
- GD_SPI_ReleaseDevice(spi_slave->spihandle);
- rt_sem_release(&spi_control->xfer_lock);
- if(ret != GD_OK)
- {
- rt_kprintf("%s,%d,transfer error!\n",__FUNCTION__,__LINE__);
- return 0;
- }
- else
- {
- return message->length;
- }
- }
- static struct rt_spi_ops gk_spi_ops = {
- .configure = gk_spi_configure, .xfer = gk_spi_xfer,
- };
- int gk_spi_probe(void *priv_data)
- {
- int ret,i;
- char spi_dev_name[20] = {0};
- char spi_bus_name[20] = {0};
- char spi_lock_name[20] = {0};
- struct gk_spi_controller *spi_control;
- struct gk_spi_controller_data *spi_controller_data = (struct gk_spi_controller_data *)priv_data;
- struct gk_spi_slave_info **control_slave;
- struct gk_spi_slave_info *spi_slave,*next_slave;
- if (!spi_controller_data)
- {
- rt_kprintf("%s,%d input param wrong!\n",__FUNCTION__,__LINE__);
- return -1;
- }
- spi_control = (struct gk_spi_controller *)rt_malloc(sizeof(struct gk_spi_controller));
- if (!spi_control)
- {
- rt_kprintf("%s,%d malloc failed!\n",__FUNCTION__,__LINE__);
- return -1;
- }
- rt_memset(spi_control, 0, sizeof(struct gk_spi_controller));
- spi_control->id = spi_controller_data->id;
- rt_sprintf(spi_lock_name, "%s%d", "spi_lock", spi_control->id);
- rt_sprintf(spi_bus_name, "%s%d", "spi_bus", spi_control->id);
- rt_sem_init(&spi_control->xfer_lock, spi_lock_name, 1, RT_IPC_FLAG_FIFO);
- ret = rt_spi_bus_register(&spi_control->spi_bus, spi_bus_name, &gk_spi_ops);
- control_slave = &spi_control->spi_slave;
- for (i = 0; i < spi_controller_data->total_slave; i++)
- {
- spi_slave = (struct gk_spi_slave_info *)rt_malloc(sizeof(struct gk_spi_slave_info));
- if (!spi_slave)
- {
- rt_kprintf("%s,%d malloc failed!\n",__FUNCTION__,__LINE__);
- goto exit;
- }
- rt_memset(spi_slave, 0, sizeof(struct gk_spi_slave_info));
- spi_slave->id = i;
- spi_slave->control = spi_control;
- spi_slave->cs_pin = spi_controller_data->slave_cs_pin[i];
- spi_slave->spihandle = -1;
- rt_sprintf(spi_dev_name, "%s%d%s%d", "ssi", spi_control->id, "_", spi_slave->id);
- *control_slave = spi_slave;
- control_slave = &spi_slave->next;
- ret = rt_spi_bus_attach_device(&spi_slave->spi_device, spi_dev_name,spi_bus_name, spi_slave);
- if (ret != RT_EOK)
- {
- rt_kprintf("register dev to bus failed...\n");
- goto exit;
- }
- }
- spi_controller_data->control = spi_control;
- GD_SPI_Init();
- return RT_EOK;
- exit:
- spi_slave = spi_control->spi_slave;
- while (spi_slave != RT_NULL)
- {
- next_slave = spi_slave->next;
- rt_free(spi_slave);
- spi_slave = next_slave;
- }
- rt_sem_detach(&spi_control->xfer_lock);
- rt_free(spi_control);
- return RT_ERROR;
- }
- int gk_spi_exit(void *priv_data)
- {
- struct gk_spi_controller *spi_control;
- struct gk_spi_controller_data *plat_data;
- struct gk_spi_slave_info *spi_slave;
- struct gk_spi_slave_info *next_slave;
- plat_data = (struct gk_spi_controller_data *)priv_data;
- spi_control = plat_data->control;
- spi_slave = spi_control->spi_slave;
- while (spi_slave != RT_NULL)
- {
- next_slave = spi_slave->next;
- rt_free(spi_slave);
- spi_slave = next_slave;
- }
- rt_sem_detach(&spi_control->xfer_lock);
- rt_free(spi_control);
- return RT_EOK;
- }
- struct gk_platform_driver gk_spi_driver_ops = {
- .name = "spi", .probe = gk_spi_probe, .remove = gk_spi_exit,
- };
- void rt_hw_spi_init(void)
- {
- gk_platform_driver_init(&gk_spi_driver_ops);
- }
|