版权声明:本文为博主原创文章,未经博主允许不得转载。转载请标注出处: https://blog.csdn.net/sheji105/article/details/82625952
驱动:
drivers/i2c/
高通平台的i2c:
drivers/i2c/busses/i2c-msm-v2.c
本产品用到i2c的地方有:camera。
以camera的i2c为例:
设备树内容内容:
i2c_3: i2c@78b7000 {- compatible = "qcom,i2c-msm-v2";
- #address-cells = <1>;
- #size-cells = <0>;
- reg-names = "qup_phys_addr";
- reg = <0x78b7000 0x1000>;
- interrupt-names = "qup_irq";
- interrupts = <0 97 0>;
- clocks = <&clock_gcc 0x8caa5b4f>,
- <&clock_gcc 0x9e25ac82>;
- clock-names = "iface_clk", "core_clk";
- qcom,clk-freq-out = <100000>;
- qcom,clk-freq-in = <19200000>;
- pinctrl-names = "i2c_active", "i2c_sleep";
- pinctrl-0 = <&i2c_3_active>;
- pinctrl-1 = <&i2c_3_sleep>;
- qcom,noise-rjct-scl = <0>;
- qcom,noise-rjct-sda = <0>;
- dmas = <&dma_blsp1 8 64 0x20000020 0x20>,
- <&dma_blsp1 9 32 0x20000020 0x20>;
- dma-names = "tx", "rx";
- qcom,master-id = <86>;
- };
根据内核配置文件和compatible = "qcom,i2c-msm-v2"; 很容易找到概述
drivers/i2c/busses/i2c-msm-v2.c。
摘取i2c-msm-v2.c中关键内容:
static struct of_device_id i2c_msm_dt_match[] = {- {
- .compatible = "qcom,i2c-msm-v2",
- },
- {}
- };
- static struct platform_driver i2c_msm_driver = {
- .probe = i2c_msm_probe,
- .remove = i2c_msm_remove,
- .driver = {
- .name = "i2c-msm-v2",
- .owner = THIS_MODULE,
- .pm = &i2c_msm_pm_ops,
- .of_match_table = i2c_msm_dt_match,
- },
- };
- static int i2c_msm_init(void)
- {
- return platform_driver_register(&i2c_msm_driver);
- }
结合linux i2c设备驱动原理,熟悉上面出现的函数。
以下函数,可对应到设备树内容中很多信息:
/*- * i2c_msm_rsrcs_process_dt: copy data from DT to platform data
- * @return zero on success or negative error code
- */
- static int i2c_msm_rsrcs_process_dt(struct i2c_msm_ctrl *ctrl,
- struct platform_device *pdev)
- {
- u32 fs_clk_div, ht_clk_div, noise_rjct_scl, noise_rjct_sda;
- int ret;
- struct i2c_msm_dt_to_pdata_map map[] = {
- {"i2c", &pdev->id, DT_REQ, DT_ID, -1},
- {"qcom,clk-freq-out", &ctrl->rsrcs.clk_freq_out,
- DT_REQ, DT_U32, 0},
- {"qcom,clk-freq-in", &ctrl->rsrcs.clk_freq_in,
- DT_REQ, DT_U32, 0},
- {"qcom,disable-dma", &(ctrl->rsrcs.disable_dma),
- DT_OPT, DT_BOOL, 0},
- {"qcom,master-id", &(ctrl->rsrcs.clk_path_vote.mstr_id),
- DT_SGST, DT_U32, 0},
- {"qcom,noise-rjct-scl", &noise_rjct_scl,
- DT_OPT, DT_U32, 0},
- {"qcom,noise-rjct-sda", &noise_rjct_sda,
- DT_OPT, DT_U32, 0},
- {"qcom,high-time-clk-div", &ht_clk_div,
- DT_OPT, DT_U32, 0},
- {"qcom,fs-clk-div", &fs_clk_div,
- DT_OPT, DT_U32, 0},
- {NULL, NULL, 0, 0, 0},
- };
- ret = i2c_msm_dt_to_pdata_populate(ctrl, pdev, map);
- if (ret)
- return ret;
- /* set divider and noise reject values */
- return i2c_msm_set_mstr_clk_ctl(ctrl, fs_clk_div, ht_clk_div,
- noise_rjct_scl, noise_rjct_sda);
- }
输入输出时钟设置:
qcom,clk-freq-out = <100000>;
qcom,clk-freq-in = <19200000>;
-
- i2c、spi、usb驱动架构的类比
这几个设备用的架构是linux常用架构之一。从板级逻辑层看,usb具有总线热拔插能力,这层对于usb设备已无意义;假如usb设备有这层代码,说明板子上有这个设备,但实际并没有usb设备,反而带来了错误。熟悉类比图中出现的函数名。