很多时候由于节省硬件资源,降低成本,会把PWM控制芯片去掉或者是改做它用,导致当我们想用PWM方式控制背光时只能使用带有clk功能的GPIO口。本篇文档就来讲解下如何使用GPIO模拟PWM功能进行背光的控制。本文以MSM8909为例。

一、选取GPIO口并进行配置

1、需要查看寄存器手册,选取对应的具有GP_CLK功能的GPIO口——gpio49。

2、我们需要先看下,该管脚是否被其他模块应用。查看配置信息,发现该管脚被默认用作了UIM2。我们要先关闭UIM模块对其的操作,如果你仅仅负责BSP领域,那么请找对应modem的同事帮忙把对这个脚的使用关掉。

3、接下来就是将该管脚配置为clk模式。

3.1 dtsi中添加节点

kernel/msm-3.18/arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi

                gpio_pwm_default: gpio_pwm_default {mux {pins = "gpio49";function = "gcc_gp1_clk_a";};config {pins = "gpio49";drive-strength = <16>;bias-disable;};};

3.2 定义设备节点

kernel/msm-3.18/arch/arm/boot/dts/qcom/msm8909-mdss.dtsi

     beeper: beeper {compatible = "gpio-beeper";pinctrl-names = "default";pinctrl-0 = <&gpio_pwm_default>;clocks = <&clock_gcc clk_gp1_clk_src>;clock-names = "gpio-pwm-clk";};

二、配置时钟信息

既然我们作为CLK使用,必然需要配置其对应的频率。

kernel/msm-3.18/drivers/clk/msm/clock-gcc-8909.c

static struct clk_freq_tbl ftbl_gcc_gp1_3_clk[] = {F(   150000,    xo,     1,      1,      128),F( 19200000,    xo, 1,  0,    0),F(   9375, xo, 16, 1,   128),//添加对应的频率信息F_END
};

分别解析一下对应的这几个值的信息:9375——对应的clk频率,xo——时钟源,16——SRC_DIV,1——M,128——N。

三、驱动适配

添加设备初始化信息    kernel/msm-3.18/drivers/video/msm/mdss/mdss_dsi.c

#include <linux/clk.h>
#include <soc/qcom/clock-local2.h>
#include <linux/io.h>
... ...
struct clk *pclk;
struct rcg_clk *gp1_rcg_clk;
extern void mdss_set_gpio_pwm(int level);static int mdss_dsi_bl_probe(struct platform_device *pdev)
{int ret;int level = 50;if (!pdev || !pdev->dev.of_node) {pr_err("%s: pdev not found for DSI controller\n", __func__);return -ENODEV;}pclk = devm_clk_get(&pdev->dev, "gpio-pwm-clk");//获取clk信息ret = clk_set_rate(pclk, 9375);//设置clk频率if (ret){printk("clk set rate fail, ret = %d\n", ret);}ret = clk_prepare_enable(pclk);//使能clkif (ret){printk("%s: clk_prepare error!!!\n", __func__);}else{printk("%s: clk_prepare success!\n", __func__);}gp1_rcg_clk = to_rcg_clk(pclk);mdss_set_gpio_pwm(level);//设置背光,个人添加的方法return 0;
}static const struct of_device_id mdss_dsi_bl_dt_match[] = {{.compatible = "gpio-beeper"},{}
};
MODULE_DEVICE_TABLE(of, mdss_dsi_bl_dt_match);static struct platform_driver mdss_dsi_bl_driver = {.probe = mdss_dsi_bl_probe,.shutdown = NULL,.driver = {.name = "beeper",.of_match_table = mdss_dsi_bl_dt_match,},
};static int mdss_dsi_bl_register_driver(void)
{return platform_driver_register(&mdss_dsi_bl_driver);
}static int __init mdss_dsi_bl_driver_init(void)
{int ret;ret = mdss_dsi_bl_register_driver();if (ret) {pr_err("mdss_dsi_bl_register_driver() failed!\n");return ret;}return ret;
}
fs_initcall(mdss_dsi_bl_driver_init);

自定义方法,该方法作为设置背光等级   kernel/msm-3.18/drivers/video/msm/mdss/mdss_dsi_panel.c

#include <linux/io.h>
#include <soc/qcom/clock-local2.h>
#include <linux/clk.h>
... ...
extern struct clk *pclk;
extern struct rcg_clk *gp1_rcg_clk;
#define CBCR_OFFSET 0x0
#define CMD_RCGR_OFFSET 0x4
#define D_OFFSET 0x14
#define GP1_CLK_BASE 0x8000void mdss_set_gpio_pwm(int level)
{int ret;ret = clk_set_rate(pclk, 9375);if (ret){printk("clk set rate fail, ret = %d\n", ret);}ret = clk_prepare_enable(pclk);if (ret){printk("%s: clk_prepare error!!!\n", __func__);}else{printk("%s: clk_prepare success!\n", __func__);}gp1_rcg_clk = to_rcg_clk(pclk);if(level == 0){mb();writel_relaxed(0x0, *gp1_rcg_clk->base + GP1_CLK_BASE + CBCR_OFFSET);//根据寄存器手册,该寄存器代表clk是否使能,写1代表enable,写0表示disable。当level值为0时将clk关闭。}else{writel_relaxed(((~(128 * level / 50)) & 0x0ff), *gp1_rcg_clk->base + GP1_CLK_BASE + D_OFFSET ); //128 is the value of N, if just output clock, please remove this line.
//此处的level即为对应的等级,这里只能为1-100,所以我们传值时要对0-255进行转换再使用。另外注意前面有取反的符号,这个是高通定死的,我们写的背光等级是对应值取反。mb();writel_relaxed(0x3, *gp1_rcg_clk->base+ GP1_CLK_BASE + CMD_RCGR_OFFSET); //RCGRmb();writel_relaxed(0x1, *gp1_rcg_clk->base + GP1_CLK_BASE + CBCR_OFFSET); //CBCR}
}

添加BL_GPIO控制选项   kernel/msm-3.18/drivers/video/msm/mdss/mdss_dsi.h

enum dsi_panel_bl_ctrl {BL_PWM,BL_WLED,BL_DCS_CMD,BL_GPIO,    //gpio控制选项UNKNOWN_CTRL,
};

根据qcom,mdss-dsi-bl-pmic-control-type选择对应的控制方式:

int mdss_panel_parse_bl_settings(struct device_node *np,struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{... ...}else if (!strcmp(data, "bl_ctrl_gpio")) {ctrl_pdata->bklt_ctrl = BL_GPIO;} else if (!strcmp(data, "bl_ctrl_pwm")) {ctrl_pdata->bklt_ctrl = BL_PWM;ctrl_pdata->pwm_pmi = of_property_read_bool(np,"qcom,mdss-dsi-bl-pwm-pmi");... ...
}

在背光控制方法中根据控制方式添加对应的背光控制函数:

static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata,u32 bl_level)
{... ...case BL_PWM:mdss_dsi_panel_bklt_pwm(ctrl_pdata, bl_level);break;case BL_GPIO:bl_level = 100*bl_level/255;//将0-255等级划分为0-100if(bl_level>99){bl_level = 99;}mdss_set_gpio_pwm(bl_level);break;... ...
}

此时我们已经设配完成,已经可以进行正常的背光亮度调节,以及量灭屏操作。

四、修改占空比

首先看下占空比公式:D/N

假设我们设置的F(100000, xo, 3, 1, 64),那么M = 1 N = 64 D = 0.5。当N为128时,D最小也可为0.5。此时我们可以看到占空比可以为1-128个等级。

M = 1 M = 0x1

N = 64 NOT_N_M = 0xFFC0

D = 0.5 NOT_2D = 0xFFFE

Resulting Clock = 0.100 MHz
Error = 0.000 MHz
Duty Cycle = 0.78%
Resulting Jitter = 0.000 ns
Period = 10000.000 ns
Pulse High = 78.125 ns
Pulse Low = 9921.875 ns

高通平台GPIO模拟PWM控制背光相关推荐

  1. 高通平台gpio简单调试

    版权声明:本文为博主原创文章,未经博主允许不得转载.    https://blog.csdn.net/u010164190/article/details/83860374 0.编译读写gpio寄存 ...

  2. 高通平台GPIO漏电问题分析方法

    在Android智能手机项目开发过程中,我们经常会遇到GPIO漏电导致系统底电流偏高.故总结一下: 1.首先建议HW将怀疑漏电的GPIO与外围电路彻底断开 2.如果依然漏电,使用命令检查GPIO状态: ...

  3. 高通平台gpio调试

    在Linux下,通过sysfs,获取gpio状态,也可以操作gpio. 1.获取gpio状态 cd /sys/kernel/debug/         cat gpio 2.调试gpio(以gpio ...

  4. 高通平台 lcd driver 调试小结

    一.概述 1.1 简介 本文档主要包括LCD模块的驱动流程分析.Framebuffer相关知识.Gralloc等相关内容,以及LCD调试的一些经验和相关bug的分析和讲解. 1.2  开发环境 And ...

  5. 高通平台android开发总结

    http://www.cnblogs.com/yuzaipiaofei/archive/2012/07/24/4124179.html 1.高通平台android开发总结 1.1 搭建高通平台环境开发 ...

  6. 高通平台android 环境配置编译及开发经验总结

    完全转自:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...

  7. 高通平台android开发总结 .

    http://blog.csdn.net/mirkerson/article/details/7691029 http://blog.csdn.net/mirkerson/article/detail ...

  8. 高通平台android 环境配置编译及开发经验总结【转】

    1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通开发板上烧录文件系统 建立高通平台开发环境 高通平台,android和 modem 编译流程分析 高通平台 7620 启动流 ...

  9. 高通平台GPS工程测试接收参数解析

    高通平台GPS工程测试&接收参数解析 前言 一.GPS工程测试 1.测试环境&仪器搭建 2.板子/整机状态 二.GPS接收机参数解析 1.灵敏度 2.空间衰减 3.SNR信噪比 4.C ...

最新文章

  1. python pip指令_python 常用 pip 命令合集
  2. Knative 入门系列1:knative 概述
  3. nodejs获取当前url和url参数值
  4. EXCEL的扩展名xls与xlsm的区别
  5. 网络营销——网络营销专员如何做好网站外链优化工作?
  6. iOS中MVC设计模式
  7. 使用MONGODB 集群的OPLOG 日志进行数据恢复
  8. 通过powerdns实现主机名解析
  9. js ejs for语句的第二种遍历用法
  10. 【编撰】linux IPC 002 - 匿名管道PIPE和有名管道FIFO的概念和实例,以及应用比较
  11. 蓝桥杯ALGO-125算法训练 王、后传说(回溯、递归)
  12. Kafka: Producer (0.10.0.0)
  13. Java加密算法(十一)——双向认证
  14. Zebra-VTYSH源码分析和改造
  15. 解决安装TortoiseSVN时,提示 Windows-Update(kb2999226)
  16. 保姆级Ruby on rails安装教程
  17. python中计算均方误差_Python中的均方根误差
  18. 20165219 《Java程序设计》实验二(Java开发环境的熟悉)实验报告
  19. 1-9DCL语言与提权逻辑
  20. 时间序列ARMA中p,q选择

热门文章

  1. 【C++】之内联函数(inline)
  2. 多重if 和 嵌套 if 选择结构
  3. 【外文翻译】外国友人写得很不错的Java Lambda表达式入门教程,我终于翻译好给大家啦!!!...
  4. 前端知识总结汇总!(HTML、CSS、JS、jQuery、vue、微信小程序)
  5. 微信小程序轮播图的实现
  6. 固定定位失效问题(position:fixed;固定定位)
  7. 拉格朗日插值法 C语言实现
  8. WebLogic 10.3.1 下载地址
  9. trinity的简介、下载及使用
  10. 1837:Balance