pinctrl子系统做功能的切换.

SD卡和debug口中sdmmc和uart共用同一组pin脚,需实现在sd使用的时候切换到sdmmc不插入sd卡的时候使用debug口功能。

sd卡有检测脚可以作为切换的标志所以我们的切换要在sd卡的驱动中去做。

第一步:

使能俩个功能的dts并去除不能切换的pinctrl,只有一个节点能使用该pin 的pinctrl,要不然其中一路会跑不下去

c 复制代码
	fiq-debugger {    //功能一
		compatible = "rockchip,fiq-debugger";
		rockchip,serial-id = <2>;
		rockchip,wake-irq = <0>;
		/* If enable uart uses irq instead of fiq */
		rockchip,irq-mode-enable = <0>;
		rockchip,baudrate = <1500000>;  /* Only 115200 and 1500000 */
		interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
		// pinctrl-names = "default";   //去除引用的pinctrl
		// pinctrl-0 = <&uart2m0_xfer>;
		status = "okay";
	};
	&sdmmc {   //功能二
	max-frequency = <25000000>;
	bus-width = <4>;
	cap-mmc-highspeed;
	cap-sd-highspeed;
	supports-sd;
	card-detect-delay = <800>;
	ignore-pm-notify;
	cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>;
	sd-uhs-sdr12;
	sd-uhs-sdr25;
	// sd-uhs-sdr50;
	// sd-uhs-sdr104;
	vqmmc-supply = <&vccio_sd>;
	vmmc-supply = <&vcc_sd>;
	pinctrl-names = "default","udbg";
	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;   //sd 卡
	pinctrl-1 = <&uart2m0_xfer &uart4_xfer &uart4_cts &uart4_rts>;  //uart function 用于debug口
	status = "okay";
};

这样当我们不使用SD卡的时候利用pinctrl直接切换到pinctrl -1这个pin的fuc就会切换到对应的pin uart状态。

方便理解,灵魂配图

我的理解是在soc中各个pIn脚都有对应的复用功能,可以当做普通gpio使用也可以当做uart 或者pwm功能使用,具体看芯片手册。

内部的原理应该和图差不多。


然后我们就要在驱动中切换状态了

首先获取dst中的状态satstu 0 和status 1对应就是dts中的pinctrl-0 pinctrl -1

c 复制代码
	if(of_property_read_bool(np, "supports-sd")){
		dw_sdpinctrl = devm_pinctrl_get(&pdev->dev);

		pins_sddefault = pinctrl_lookup_state(dw_sdpinctrl,"default");
		pins_sdudbg = pinctrl_lookup_state(dw_sdpinctrl,"udbg");
		if (IS_ERR(pins_sddefault) || IS_ERR(pins_sdudbg))
			pr_err(" %s pinctrl_lookup_state default | udbg status failed.\n",__func__);

		if(debug_mode)
			pinctrl_select_state(dw_sdpinctrl,pins_sdudbg);
		else
			pinctrl_select_state(dw_sdpinctrl,pins_sddefault);
	}

然后在插卡的时候做切换

c 复制代码
	if(mmc->restrict_caps & RESTRICT_CARD_TYPE_SD){
		present = !gpio_get_value(gpio_detect);
        /* Card insert, switch data line to uart function, and vice verse.
        ONLY audi chip need switched by software, using udbg tag in dts!
        */
		if (!(IS_ERR(pins_sddefault)) &&!(IS_ERR(pins_sdudbg))) {
			if (!present && debug_mode) {
				if (pinctrl_select_state(dw_sdpinctrl,pins_sdudbg) < 0)
					dev_err(host->dev,"sdmmc Udbg pinctrl setting failed!\n");
			} else {
				if (pinctrl_select_state(dw_sdpinctrl,pins_sddefault) < 0)
					dev_err(host->dev,"sdmmc Default pinctrl setting failed!\n");
			}
		}
	}

流程是

1、devm_pinctrl_get获取pinctrl

2、pinctrl_lookup_state获取对应的status 0 1 2 。。。

3、pinctrl_select_state根据判断切换到对应的pin status

切换到对应的Pin status之后由于我们的debug口驱动也在正常跑它使用serirl 2作为控制台输出口注册成ttyFIQ0。

一般pin ctrl的切换只在同一个驱动中使用。这种跨驱动的使用之前还是没见过的,记录一下。这种使用方式还是有比较多限制的。

(在debug口中只是使用了uart2,但是uart2的pinctrl没有明确是哪路引脚他也不报错。并且切换到uart2的func就能正常输出。)

相关推荐
段ヤシ.1 小时前
银河麒麟(内核CentOS8)安装rbenv、ruby2.6.5和rails5.2.6
linux·centos·银河麒麟·rbenv·ruby2.6.5·rails 5.2.6
深夜情感老师3 小时前
centos离线安装ssh
linux·centos·ssh
菜鸟射手7 小时前
QT creater和vs2017文件路径问题
linux·c++·windows·qt
@Aurora.7 小时前
【项目日记(三)】
linux·服务器·网络
白总Server8 小时前
Nginx 中间件
大数据·linux·运维·服务器·nginx·bash·web
望获linux9 小时前
实时操作系统在服务型机器人中的关键作用
linux·机器人·操作系统·开源软件·rtos·具身智能
哈哈幸运9 小时前
Linux Sed 深度解析:从日志清洗到 K8s 等12个高频场景
linux·运维·编辑器·sed
心随_风动9 小时前
主流操作系统对比分析(macOS、Linux、Windows、Unix)
linux·windows·macos
啊吧怪不啊吧10 小时前
Linux常见指令介绍下(入门级)
linux·开发语言·centos
陈大大陈11 小时前
基于 C++ 的用户认证系统开发:从注册登录到Redis 缓存优化
java·linux·开发语言·数据结构·c++·算法·缓存