/***************************************************************************************************************************
**原创:http://blog.csdn.net/kylin_fire_zeng , 欢迎转载分享,共同进步,但请注明出处啊,尊重他人成果。
***************************************************************************************************************************/
蓝牙驱动:
dts配置:
-----------------------
arch/arm/boot/dts/rk3128-box-rk88.dts"
-->
wireless-bluetooth {
compatible = "bluetooth-platdata";
//wifi-bt-power-toggle;
uart_rts_gpios = <&gpio0GPIO_C1 GPIO_ACTIVE_LOW>;
pinctrl-names ="default","rts_gpio";
pinctrl-0 =<&uart0_rts>;
pinctrl-1 =<&uart0_rts_gpio>;
//BT,power_gpio =<&gpio4 GPIO_D3 GPIO_ACTIVE_HIGH>;
BT,reset_gpio = <&gpio3GPIO_C5 GPIO_ACTIVE_HIGH>;
BT,wake_gpio = <&gpio3GPIO_C4 GPIO_ACTIVE_HIGH>;
BT,wake_host_irq =<&gpio3 GPIO_C6 GPIO_ACTIVE_LOW>;
status = "okay";
};
&uart0{
status = "okay";
dma-names = "!tx","!rx";
pinctrl-0 = <&uart0_xfer&uart0_cts>;
};
----------------------------
kernel/arch/arm/boot/dts/rk312x.dtsi
正在的uart0 配置在:
uart0: serial@20060000 {
compatible ="rockchip,serial";
reg = <0x20060000 0x100>;
interrupts = <GIC_SPI 20IRQ_TYPE_LEVEL_HIGH>;
clock-frequency =<24000000>;
clocks =<&clk_uart0>, <&clk_gates8 0>;
clock-names ="sclk_uart", "pclk_uart";
reg-shift = <2>;
reg-io-width = <4>;
dmas = <&pdma 2>,<&pdma 3>;
#dma-cells = <2>;
pinctrl-names ="default";
pinctrl-0 = <&uart0_xfer&uart0_cts &uart0_rts>;
status = "disabled";
};
-----------------------------
kernel/arch/arm/boot/dts/rk312x-pinctrl.dtsi
gpio0_uart0 {
uart0_xfer: uart0-xfer{
rockchip,pins =<UART0_SIN>,
<UART0_SOUT>;
rockchip,pull =<VALUE_PULL_UPDOWN_DISABLE>;
};
uart0_cts: uart0-cts {
rockchip,pins =<UART0_CTSN>;
/* rockchip,pull =<VALUE_PULL_DEFAULT>; */
rockchip,pull =<VALUE_PULL_UPDOWN_DISABLE>;
};
uart0_rts: uart0-rts {
rockchip,pins =<UART0_RTSN>;
/* rockchip,pull =<VALUE_PULL_DEFAULT>; */
rockchip,pull= <VALUE_PULL_UPDOWN_DISABLE>;
};
uart0_rts_gpio:uart0-rts-gpio {
rockchip,pins =<FUNC_TO_GPIO(UART0_RTSN)>;
/* rockchip,pull =<VALUE_PULL_DEFAULT>; */
rockchip,pull =<VALUE_PULL_UPDOWN_DISABLE>;
};
};
------------------
arch/arm/boot/dts/include/dt-bindings/pinctrl/rockchip-rk312x.h
#define UART0_SOUT0x2d22
#define UART0_SIN0x2d32
#define UART0_CTSN0x2d52
那上面关系完了。我们就开始讲解驱动了吧。
驱动:net/rfkill/rfkill-bt.c
----->
static int __initrfkill_rk_init(void)
{
LOG("Enter %s\n", __func__);
returnplatform_driver_register(&rfkill_rk_driver);
}
static structplatform_driver rfkill_rk_driver = {
.probe= rfkill_rk_probe,
.remove= rfkill_rk_remove,
.driver= {
.name= "rfkill_bt",
.owner= THIS_MODULE,
.pm= &rfkill_rk_pm_ops,
.of_match_table = of_match_ptr(bt_platdata_of_match),
},
};
static structof_device_id bt_platdata_of_match[] = {
{ .compatible = "bluetooth-platdata"},
{ }
};
这里的这个跟
wireless-bluetooth {
compatible = "bluetooth-platdata";
………
}
刚好匹配上了。Ok,那就行了。进入rfkill_rk_probe 吧.
static intrfkill_rk_probe(struct platform_device *pdev)
{
structrfkill_rk_data *rfkill;
structrfkill_rk_platform_data *pdata = pdev->dev.platform_data;
pdata = devm_kzalloc(&pdev->dev,sizeof(struct rfkill_rk_platform_data), GFP_KERNEL);
ret =bluetooth_platdata_parse_dt(&pdev->dev, pdata);----->@1
pdata->name= (char*)bt_name;
pdata->type =RFKILL_TYPE_BLUETOOTH;
rfkill =devm_kzalloc(&pdev->dev, sizeof(*rfkill), GFP_KERNEL);
rfkill->pdata= pdata;
rfkill->pdev = pdev;
g_rfkill = rfkill;
bluetooth_dir= proc_mkdir("bluetooth", NULL);
sleep_dir = proc_mkdir("sleep",bluetooth_dir);
ent = proc_create("lpm", 0,sleep_dir, &bluesleep_lpm);
ent = proc_create("btwrite", 0,sleep_dir, &bluesleep_btwrite);
---
注册对应的管脚功能。
ret = rfkill_rk_setup_gpio(pdev,&pdata->poweron_gpio, pdata->name, "poweron");
ret = rfkill_rk_setup_gpio(pdev,&pdata->reset_gpio, pdata->name, "reset");
ret = rfkill_rk_setup_gpio(pdev,&pdata->wake_gpio, pdata->name, "wake");
ret = rfkill_rk_setup_gpio(pdev,&pdata->rts_gpio, rfkill->pdata->name, "rts");
wake_lock_init(&(rfkill->bt_irq_wl), WAKE_LOCK_SUSPEND,"rfkill_rk_irq_wl");
ret = rfkill_rk_setup_wake_irq(rfkill);
这里进行了注册。
ret= rfkill_register(rfkill->rfkill_dev);
platform_set_drvdata(pdev,rfkill);
LOG("%sdevice registered.\n", pdata->name);
这里整个
}
@1 :
static intbluetooth_platdata_parse_dt(struct device *dev,
structrfkill_rk_platform_data *data)
{
if (of_find_property(node, "wifi-bt-power-toggle", NULL)){}
gpio = of_get_named_gpio_flags(node,"uart_rts_gpios", 0, &flags);
gpio= of_get_named_gpio_flags(node, "BT,power_gpio", 0, &flags);
gpio = of_get_named_gpio_flags(node,"BT,reset_gpio", 0, &flags);
gpio= of_get_named_gpio_flags(node, "BT,wake_gpio", 0, &flags);
gpio= of_get_named_gpio_flags(node, "BT,wake_host_irq", 0, &flags);
自己跟下面的dts配置比较一下吧。
----------> 这里可以单独其实就是读取dts文件,然后赋值给 *data 函数。
}
原文地址:http://blog.csdn.net/kylin_fire_zeng/article/details/46332507