|
发表于 2020-11-3 20:03:44
6070 浏览 0 回复
MTK 驱动 Kernel-3.18中如何配置和使用spi
[DESCRIPTION]
(1)kernel-3.18中使用了device tree机制,可以通过device tree来配置spi device。
(2)使用DMA 方式传输时,需要正确申请buffer,才能传输成功。
[SOLUTION]
kernel-3.18中使用 spi 的步骤:
Step1:添加 spi device:
- 在$(project).dts文件的末尾增加spi device,example:在spi0上增加device
- &spi0{
- #address-cells = <1>;
- #size-cells = <0>;
- test_spi{
- compatible = "test_spi_device"; /*set spi->modalias must*/
- reg = <0>; /*set spi->chip_select must*/
- spi-max-frequency = <1000000>; /*set spi->max_speed_hz must*/
- /*other infromation*/
- /*spi-cpha;*/ /*set cpha=1, optional*/
- /*spi-cpol;*/ /*set cpol=1, optional*/
- /*spi-cs-high;*/ /*set cs active level=1, optional*/
- /*spi-3wire;*/ /*set no-tx or no-rx, optional*/
- /*spi-lsb-first;*/ /*set lsb-first transfer, optional*/
- };
- };
复制代码
Step2:添加 spi driver
- 在driver中添加spi_driver,example:
- #if defined(CONFIG_OF)
- static struct of_device_id test_match_table[] = {
- {.compatible = "test_spi_device",}, /*与devicetree中的spi device的compatible一致*/
- {},
- };
- #endif
- static struct spi_driver spi_test_driver = {
- .driver = {
- .name = "test_spi",
- .owner = THIS_MODULE,
- #if defined(CONFIG_OF)
- .of_match_table = test_match_table,
- #endif
- },
- .probe = spi_test_probe,
- .remove = spi_test_remove,
- //...
- };
复制代码
Step3:配置spi的参数
在driver中配置spi的传输参数,example:
- #include <mt_spi.h>
- int spi_set_para(struct spi_device *spidev)
- {
- struct mt_chip_conf *chip_config = NULL;
-
- if(spidev == NULL){
- pr_err("%s spidev is null.\n", __func__);
- return -EINVAL;
- }
- chip_config = (struct mt_chip_conf *)spidev->controller_data;
- if(chip_config == NULL){
- pr_err("%s chip_config is null.\n", __func__);
- return -EINVAL;
- }
- spi_bus_lock(spidev->master); // lock bus
- /*****这里修改设定您想要修改的参数*****/
- chip_config->setuptime = 3; /*传输开始时cs信号的setup时间(cs开始 -> clk开始)*/
- chip_config->holdtime = 3; /*传输结束后cs信号的保持时间(clk停止 -> cs停止)*/
- chip_config->high_time = 10; /*clk高电平持续时间*/
- chip_config->low_time = 10; /*clk低电平持续时间*/
- chip_config->cs_idletime = 2; /*cs空闲时间*/
- chip_config->ulthgh_thrsh = 0; /*未使用*/
- chip_config->cs_pol = 0; /*cs有效电平*/
- chip_config->sample_sel = 0; /**/
- chip_config->cpol = 0; /*clk空闲时的电平*/
- chip_config->cpha = 1; /*mosi/miso的采样点(0:前沿; 1:后沿)*/
- chip_config->rx_mlsb = 1; /*rx是否高位先发送(1:先发msb; 0:先发lsb)*/
- chip_config->tx_mlsb = 1; /*tx是否高位先发送(1:先发msb; 0:先发lsb)*/
- chip_config->tx_endian = 0; /*tx发送数据的端序(仅DMA mode有效)*/
- chip_config->rx_endian = 0; /*rx发送数据的端序(仅DMA mode有效)*/
- chip_config->com_mod = DMA_TRANSFER; /*传输mode: FIFO_TRANSFER or DMA_TRANSFER*/
- chip_config->pause = 0; /*是否开启pause mode(1:enable; 0:disable)*/
- chip_config->finish_intr = 1; /*是否打开传输完成的中断(1:打开; 0:不打开, code默认是打开的)*/
- chip_config->deassert = 0; /*是否使用deassert mode,一般不使用*/
- chip_config->ulthigh = 0; /*未使用*/
- chip_config->tckdly = 0; /*一般设置为0*/
- /*end*/
-
- spi_setup(spidev);
- spi_bus_unlock(spidev->master); // unlock bus
-
- return 0;
- }
复制代码
Step4:使用spi传输
(1)FIFO mode
a。将spi 参数设置为FIFO mode,
chip_config->com_mod = FIFO_TRANSFER;
b。然后使用linux标准的spi传输函数进行数据传输,一般使用 spi_sync().
int spi_sync(struct spi_device *spi, struct spi_message *message);
(2)DMA mode
a。将spi 参数设置为DMA mode,
chip_config->com_mod = DMA_TRANSFER;
b。申请buf,需要使用flag: GFP_DMA
buf = kzalloc(buf_len, GFP_KERNEL | GFP_DMA);
c。然后使用linux标准的spi传输函数进行数据传输,一般使用 spi_sync().
Note:
(1) $(project) 是指工程名。example:evb6755_64。
(2)当使用DMA方式进行传输时,请将 spi_transfer中的tx_buf和rx_buf都设置上,不要设置为NULL.
|
|
手机微信同号:13682654092
|
|
|
|
|
登录或注册
|