一、dts配置
spi1: spi@ff1d0000 {
compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
reg = <0x0 0xff1d0000 0x0 0x1000>;
clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
clock-names = "spiclk", "apb_pclk";
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
/* Firefly SPI demo */
&spi1 {
spi_demo: spi-demo@00{
status = "disabled";
compatible = "firefly,rk3399-spi";
reg = <0x00>;
spi-max-frequency = <48000000>;
/* rk3399 driver support SPI_CPOL | SPI_CPHA | SPI_CS_HIGH */
//spi-cpha; /* SPI mode: CPHA=1 */
//spi-cpol; /* SPI mode: CPOL=1 */
//spi-cs-high;
};
};
二、kernel\drivers\spi\spi-rockchip.c 里面的rockchip_spi_probe函数调用devm_spi_register_master。
三、kernel\drivers\spi\spi.c devm_spi_register_master会调用spi.c文件里面的spi_register_master。
四、spi_register_master会调用of_register_spi_devices
五、of_register_spi_devices里面会遍历所有的node,每个node都调用of_register_spi_device。
六、of_register_spi_device会设置SPI 的工作模式,然后调用spi_add_device,添加spi设备。
七、spi_add_device里面调用spi_setup设置spi参数。
八、spi_setup函数,完成spi参数设置。
int spi_setup(struct spi_device *spi)
{
unsigned bad_bits, ugly_bits;
int status;
/* check mode to prevent that DUAL and QUAD set at the same time
*/
if (((spi->mode & SPI_TX_DUAL) && (spi->mode & SPI_TX_QUAD)) ||
((spi->mode & SPI_RX_DUAL) && (spi->mode & SPI_RX_QUAD))) {
dev_err(&spi->dev,
"setup: can not select dual and quad at the same time\n");
return -EINVAL;
}
/* if it is SPI_3WIRE mode, DUAL and QUAD should be forbidden
*/
if ((spi->mode & SPI_3WIRE) && (spi->mode &
(SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)))
return -EINVAL;
/* help drivers fail *cleanly* when they need options
* that aren't supported with their current master
*/
bad_bits = spi->mode & ~spi->master->mode_bits;
ugly_bits = bad_bits &
(SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD);
if (ugly_bits) {
dev_warn(&spi->dev,
"setup: ignoring unsupported mode bits %x\n",
ugly_bits);
spi->mode &= ~ugly_bits;
bad_bits &= ~ugly_bits;
}
if (bad_bits) {
dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
bad_bits);
return -EINVAL;
}
if (!spi->bits_per_word)
spi->bits_per_word = 8;
status = __spi_validate_bits_per_word(spi->master, spi->bits_per_word);
if (status)
return status;
if (!spi->max_speed_hz)
spi->max_speed_hz = spi->master->max_speed_hz;
if (spi->master->setup)
status = spi->master->setup(spi);
spi_set_cs(spi, false);
dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n",
(int) (spi->mode & (SPI_CPOL | SPI_CPHA)),
(spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",
(spi->mode & SPI_LSB_FIRST) ? "lsb, " : "",
(spi->mode & SPI_3WIRE) ? "3wire, " : "",
(spi->mode & SPI_LOOP) ? "loopback, " : "",
spi->bits_per_word, spi->max_speed_hz,
status);
return status;
}