2021-08-17 linux spi驱动注册流程分析

一、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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值