精华内容
下载资源
问答
  • 电源管理,更新驱动。bios 灰色的: 这里取消

    没电源管理,更新驱动。bios
    灰色的:
    在这里插入图片描述
    这里取消在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 升级到了Windows10 2004,发现每次睡眠后QQ和微信消息都收不到了,去网卡的属性界面却找不到电源管理面板,并且电源计划中也只能创建平衡的电源计划。在网上找了很多解决办法,最多的是关于一个改注册表中的更改...

    问题

    升级到了Windows10 2004,发现每次睡眠后QQ和微信消息都收不到了,去网卡的属性界面却找不到电源管理面板,并且电源计划中也只能创建平衡的电源计划。在网上找了很多解决办法,最多的是关于一个改注册表中的更改注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power下面的CsEnabled的值,但尝试后依然无效。

    解决

    在设备管理器-人体学输入设备-符合蓝牙低能耗GATT的HID设备 上右键属性,点击电源管理,将“允许计算机关闭此设备以节约电源”前的勾取消掉,保存。
    在这里插入图片描述

    再去创建电源计划时已经能够创建其他两个电源计划
    在这里插入图片描述

    打开无线网卡适配器的属性界面发现电源管理标签已经恢复,将“允许计算机关闭此设备以节约电源”前的勾取消掉,保存即可
    在这里插入图片描述

    展开全文
  • 由于某度众所周知的举动,让我搬离写了5年的渣度空间,准备把...当你不想几十分钟后你的笔记本就关闭硬盘,待机,想在在控制面板里的电源选项里调整,会发现电源选项全部不可用。 这是联想自作多情的energy man

    由于某度众所周知的举动,让我搬离写了5年的渣度空间,准备把技术性的文章定在CSDN了。这些都是文章备份。勿怪。。


    当你不想几十分钟后你的笔记本就关闭硬盘,待机,想在在控制面板里的电源选项里调整,会发现电源选项全部不可用。


    这是联想自作多情的energy management(电源管理软件)搞得鬼。

    我原来删除过这货,不过很多fn功能都不可用了,所以你别给这爷爷真删了,

    正确的做法是,在控制面板的添加或删除软件里

    找到这个乱办事的蓝色小图标,点击点击更改修改,把 energy management的勾去掉,再重启电脑就行了。

    PS:联想的网站服务与下载慢得令人发指啊有木有啊!还要装控件找该死的机器号才能下载有木有?
    展开全文
  • Linux电源管理

    千次阅读 2019-05-06 09:17:56
    CSDN仅用于增加百度收录权重,排版未...探究Linux电源管理模型,并为Tiny4412的LCD驱动添加电源管理。 这是2018的第一篇博客,选了一个几乎没有接触过的角度作为开篇,希望2018年学习更多,记录更多。 1.电源管理...

    CSDN仅用于增加百度收录权重,排版未优化,日常不维护。请访问:www.hceng.cn 查看、评论。
    本博文对应地址: https://hceng.cn/2018/01/18/Linux电源管理/#more

    探究Linux电源管理模型,并为Tiny4412的LCD驱动添加电源管理。

    这是2018的第一篇博客,选了一个几乎没有接触过的角度作为开篇,希望2018年学习更多,记录更多。

    1.电源管理的两种模型

    以往接触的Linux驱动,没遇到使用电池供电的情况,因此几乎没关注电源的管理。
    然而实际中,不少使用电池供电的硬件平台,例如手机、POS机等,就需要对电源进行管理,比如在不使用设备的时候,休眠屏幕省电。

    Linux电源管理模型有两种:系统睡眠模型suspendRuntime电源管理模型

    1.1系统睡眠模型Suspend

    On (on)                  S0 - Working
    Standby (standby)            S1 - CPU and RAM are powered but not executed
    Suspend to RAM (mem)          S3 - RAM is powered and the running content is saved to RAM
    Suspend to Disk, Hibernation (disk)    S4 - All content is saved to Disk and power down

    S3 aka STR(suspend to ram),挂起到内存,简称待机。计算机将目前的运行状态等数据存放在内存,关闭硬盘、外设等设备,进入等待状态。此时内存仍然需要电力维持其数据,但整机耗电很少。恢复时计算机从内存读出数据,回到挂起前的状态,恢复速度较快。对DDR的耗电情况进行优化是S3性能的关键,大多数手持设备都是用S3待机。

    S4 aka STD(suspend to disk),挂起到硬盘,简称休眠。把运行状态等数据存放在硬盘上某个文件或者某个特定的区域,关闭硬盘、外设等设备,进入关机状态。此时计算机完全关闭,不耗电。恢复时计算机从休眠文件/分区中读出数据,回到休眠前的状态,恢复速度较慢

    系统休眠模型给我的感觉是以整机角度进行省电。
    S3类似电脑的睡眠,在教长时间不使用电脑后,电脑黑屏,再次敲击键盘迅速显示桌面,原来的工作内容仍不变。
    S4类似电脑的休眠,在长时间不使用电脑后,电脑黑屏,再次敲击键盘无反应,按下电源键,开机,原来的工作内容仍不变。

    对于嵌入式设备,更多的是使用S3,将数据暂时放在内存里,以实现快速恢复,就像手机的电源键按下黑屏,再次按下迅速亮屏。

    在Linux中,通过cat /sys/power/state可以得知当前设备支持的节能模式,一般情况有如下选项:

    • freeze:不涉及具体的Hardware或Driver,只是冻结所有的进程,包括用户空间进程及内核线程,能节省的能量较少,使用场景不多;
    • standby:前面的S1状态,CPU处于浅睡眠模式,主要针对CPU功耗;
    • mem:前面的S3状态,Suspend to RAM;
    • disk:前面的S4状态,Suspend to Disk;

    需要设置以上模式,只需echo mem > /sys/power/state即可。

    1.2 Runtime电源管理模型

    Runtime电源管理模型给我的感觉是以模块角度进行省电。
    某种程度上是“高内聚和低耦合”的体现。
    每个设备(包括CPU)都处理好自身的电源管理工作,尽量以最低的能耗完成交代的任务,尽量在不需要工作的时候进入低功耗状态,尽量不和其它模块有过多耦合。每个设备都是最节省的话,整个系统一定是最节省的。

    2. 系统睡眠模型suspend

    2.1 Suspend流程分析

    suspend的流程还是挺复杂的,向/sys/power/state写入命令后再到唤醒,将进行以下流程:

    • 对源码进行分析,其休眠过程如下:

      驱动程序里休眠相关的电源管理函数的调用过程:prepare—>suspend—>suspend_late—>suspend_noirq

    • 对源码进行分析,其唤醒过程如下:

      驱动程序里唤醒相关的电源管理函数的调用过程:resume_noirq—>resume_early—>resume->complete

    对于驱动程序,我们主要关心Device PM(针对每一个驱动)和少量Platform dependent PM(针对CPU芯片相关)的内容。

    2.2 使用Suspend功能

    首先将suspend功能加入内核:

    Power management options  --->
        [*] Suspend to RAM and standby
    

    这里默认是勾选上了的,就不管了。

    进入Tiny4412内核,尝试休眠echo mem > /sys/power/state,系统提示**No wake-up sources!**。

    可见,要进入休眠,必须要有唤醒源,没有唤醒源,休眠也没有意义。

    2.2.1 设置唤醒源

    唤醒源最常见的就是按键中断,就如同手机进入锁屏状态下,按下电源键唤醒一样,因此先写一个按键驱动。

    • 原理图:

      底板上有四个按键,分别连在GPX3_2、GPX3_3、GPX3_4、GPX3_5,引脚状态常高,按键按下变低电平。

    • 设备树:

        button_interrupt: button_interrupt {
            compatible         = "tiny4412,button_interrupt";
            tiny4412,gpx3_2 = <&gpx3 2 GPIO_ACTIVE_HIGH>;
            tiny4412,gpx3_3 = <&gpx3 3 GPIO_ACTIVE_HIGH>;
            tiny4412,gpx3_4 = <&gpx3 4 GPIO_ACTIVE_HIGH>;
            tiny4412,gpx3_5 = <&gpx3 5 GPIO_ACTIVE_HIGH>;
        };      
    
    • 按键驱动:
            //设置为中断唤醒源
            irq_set_irq_wake(irq, 1);
    
    #ifdef CONFIG_PM_SLEEP
    static int usb4604_i2c_suspend(struct device *dev)
    {
    	struct i2c_client *client = to_i2c_client(dev);
    	struct usb4604 *hub = i2c_get_clientdata(client);
    
    	usb4604_switch_mode(hub, USB4604_MODE_STANDBY);
    
    	return 0;
    }
    
    static int usb4604_i2c_resume(struct device *dev)
    {
    	struct i2c_client *client = to_i2c_client(dev);
    	struct usb4604 *hub = i2c_get_clientdata(client);
    
    	usb4604_switch_mode(hub, hub->mode);
    
    	return 0;
    }
    #endif
    
    static SIMPLE_DEV_PM_OPS(usb4604_i2c_pm_ops, usb4604_i2c_suspend,
    		usb4604_i2c_resume);       
    

    2.2.2 休眠唤醒(未成功)

    加入中断源后,休眠过程不再提示No wake-up sources!,看样子休眠应该成功了。

    此时,按下按键,板子并未唤醒,琢磨了一阵,初步怀疑有以下原因:

    • 唤醒的时候,应该需要uboot配合,uboot读取某个寄存器来判断是正常启动还是唤醒;
    • Exynos4412的PMU特性没摸透,可能需要其它额外的操作;
    • Exynos4412启动时的BL1和BL2,可能也有影响;

    这里先卡住,继续后面。

    2.3 使驱动支持Suspend

    2.3.1 通知Notifier

    前面的suspend流程分析里面,
    冻结APP之前,使用pm_notifier_call_chain(PM_SUSPEND_PREPARE)来通知驱动程序;
    重启APP之后,使用pm_notifier_call_chain(PM_POST_SUSPEND)来通知驱动程序;

    因此,如果驱动程序有事情在上述时机要处理,可以使用notifier机制。
    使用步骤:

    a.定义notifier_block结构体

    static struct notifier_block lcd_pm_notif_block = {
    	.notifier_call = lcd_suspend_notifier,
    };
    

    b.notifier操作函数

    static int lcd_suspend_notifier(struct notifier_block *nb, unsigned long event, void *dummy)
    {
    	switch (event) {
    	case PM_SUSPEND_PREPARE:
    		printk("lcd suspend notifiler test: PM_SUSPEND_PREPARE\n");
    		return NOTIFY_OK;
    	case PM_POST_SUSPEND:
    		printk("lcd suspend notifiler test: PM_POST_SUSPEND\n");
    		return NOTIFY_OK;
    
    	default:
    		return NOTIFY_DONE;
    	}
    }
    

    c.注册notifier
    在驱动init()或probe()里注册:

    	ret = register_pm_notifier(&lcd_pm_notif_block);
        if(ret) {
            printk("failed to register pm notifier.\n");
            return  -EINVAL;
        }
    

    在前面LCD驱动上修改lcd_drv.c,测试如下:

    2.3.2 Suspend和Resume

    前面的notifier只是通知,在冻结APP之前重启APP之后通知,
    而电源管理应该刚好相反,是在冻结APP之后重启APP之前对驱动的电源进行控制,
    这就需要suspendresume来实现。

    • a.在platform_driver里的driver里添加pm结构体:
    static struct platform_driver lcd_driver =
    {
        .driver        = {
            .name           = "lcd_s702",
            .pm             = &lcd_pm,
            .of_match_table = of_match_ptr(lcd_dt_ids),
        },
        .probe         = lcd_probe,
        .remove        = lcd_remove,
    };
    
    • b.设置pm成员函数:
    static struct dev_pm_ops lcd_pm = {
    	.suspend = s702_lcd_suspend,
    	.resume  = s702_lcd_resume,	
    };
    
    • c.编写成员函数:
      {% codeblock lang:c %}
      static int s702_lcd_suspend(struct device *dev)
      {
      //lcd休眠操作
      //Direct Off: ENVID and ENVID_F are set to “0” simultaneously.
      unsigned int temp;

      printk(“enter %s\n”, func);

      temp = readl(lcd_regs_base + VIDCON0);
      temp &= ~(0x01 << 1 | 0x01 << 0);
      writel(temp, lcd_regs_base + VIDCON0);

      return 0;
      }

    static int s702_lcd_resume(struct device *dev)
    {
    //lcd唤醒操作
    //Display On: ENVID and ENVID_F are set to “1”.
    unsigned int temp;

    printk("enter %s\n", __func__);
    
    temp = readl(lcd_regs_base + VIDCON0);
    writel(temp | (0x01 << 1) | (0x01 << 0), lcd_regs_base + VIDCON0);
    
    return 0;
    

    }
    {% endcodeblock %}

    这里只是简单的关闭/打开显示,理论上的操作应该是:
    休眠时先备份所有LCD相关寄存器,恢复时再恢复所有寄存器,以及其它可能操作,比如重新开启时钟等。

    同理,因为LCD显示和backlight是分开的,因此需要在backlight里也进行类似操作。

    3.Runtime电源管理模型

    前面的suspend系统睡眠模型是将整个系统进行休眠,但如果需要在系统运行时,单独对某个模块进行休眠,就需要Runtime电源管理模型,这两个模型互相协作,才能最大的发挥电源管理的效果。

    Runtime电源管理模型的原理比较简单,就是计数,
    当该设备驱动被使用时就加1,放弃使用时就减1,
    计数大于1时,就打开该设备的电源,等于0时就关闭电源。

    Runtime PM相关的函数:
    a. 使能/禁止 Runtime PM:pm_runtime_enable / pm_runtime_disable (修改disable_depth变量)
    b. 增加计数/减少计数:pm_runtime_get_sync / pm_runtime_put_sync (修改usage_count变量)
    c. 回调函数 暂停/恢复/空闲:runtime_suspend / runtime_resume / runtime_idle

    3.1 Runtime流程分析

    • 调用pm_runtime_get_sync增加使用次数以及恢复的流程如下:

    • 调用pm_runtime_put_sync减少使用次数以及暂停的流程如下:

    前面的两个流程,只看到了runtime_resumeruntime_idle的调用,没有看到runtime_suspend
    实际上,如果设备不提供runtime_idle, 则最终会调用runtime_suspend

    3.2 使用Runtime功能

    首先将Runtime功能加入内核,但本内核4.13.9里没找到相关选项,应该默认已经加入到内核里面了。

    • 调用方式一
      驱动程序提供接口, APP来调用。
      在驱动函数的open()close()里,增加和减少引用计数。
      APP调用驱动的时候就能相应的恢复、暂停设备。

    • 调用方式二
      直接操作应用层文件:
      恢复:

    echo on >  /sys/devices/.../power/control
    

    流程:control_store(drivers\base\power\sysfs.c) -> pm_runtime_forbid -> atomic_inc -> rpm_resume

    暂停:

    echo auto >  /sys/devices/.../power/control
    

    流程:control_store(drivers\base\power\sysfs.c) -> pm_runtime_allow -> atomic_dec_and_test -> rpm_idle

    3.3 使驱动支持Runtime

    • a.在platform_driver里的driver里添加pm结构体:(和前面的一样,这里就无需操作)
    static struct platform_driver lcd_driver =
    {
        .driver        = {
            .name           = "lcd_s702",
            .pm             = &lcd_pm,
            .of_match_table = of_match_ptr(lcd_dt_ids),
        },
        .probe         = lcd_probe,
        .remove        = lcd_remove,
    };
    
    • b.设置pm成员函数:
    static struct dev_pm_ops lcd_pm =
    {
        .suspend = s702_lcd_suspend,
        .resume  = s702_lcd_resume,
        .runtime_suspend = s702_lcd_suspend,
        .runtime_resume  = s702_lcd_resume,
    };
    

    添加runtime_suspendruntime_resume,runtime和suspend的暂停配置是一样的,直接使用前面的。

    • c.编写成员函数:(和前面的一样,这里就无需操作)
      {% codeblock lang:c %}
      static int s702_lcd_suspend(struct device *dev)
      {
      //lcd休眠操作
      //Direct Off: ENVID and ENVID_F are set to “0” simultaneously.
      unsigned int temp;

      printk(“enter %s\n”, func);

      temp = readl(lcd_regs_base + VIDCON0);
      temp &= ~(0x01 << 1 | 0x01 << 0);
      writel(temp, lcd_regs_base + VIDCON0);

      return 0;
      }

    static int s702_lcd_resume(struct device *dev)
    {
    //lcd唤醒操作
    //Display On: ENVID and ENVID_F are set to “1”.
    unsigned int temp;

    printk("enter %s\n", __func__);
    
    temp = readl(lcd_regs_base + VIDCON0);
    writel(temp | (0x01 << 1) | (0x01 << 0), lcd_regs_base + VIDCON0);
    
    return 0;
    

    }
    {% endcodeblock %}

    • d.使能Runtime:
      对于Runtime PM,默认状态下设备的状态是Suspended,
      如果硬件上它是运行状态,需要调用pm_runtime_set_active()来修改它的状态,
      然后调用pm_runtime_enable()来使能Runtime PM。

    probe()函数的后面添加:

        pm_runtime_set_active(&pdev->dev);
        pm_runtime_enable(&pdev->dev);
    

    反之,还要在remove()里禁止:

    pm_runtime_disable(&pdev->dev);
    
    • e.修改计数:
      一般在open()release()里面增加和减少引用计数:
      {% codeblock lang:c %}
      static int s702_lcd_open(struct fb_info *info, int user)
      {
      struct device *dev = info->dev;
      int ret;

      printk(“enter %s\n”, func);

      ret = pm_runtime_get_sync(dev);
      if (ret < 0 && ret != -EACCES)
      {
      pm_runtime_put_sync(dev);
      return ret;
      }

      return 0;
      }
      static int s702_lcd_release(struct fb_info *info, int user)
      {
      struct device *dev = info->dev;

      printk(“enter %s\n”, func);

      pm_runtime_put_sync(dev);

      return 0;
      }

    static struct fb_ops tiny4412_lcdfb_ops =
    {
    .owner = THIS_MODULE,
    .fb_setcolreg = cfb_setcolreg, //设置调色板,实现伪颜色表
    .fb_fillrect = cfb_fillrect, //填充矩形
    .fb_copyarea = cfb_copyarea, //数据复制
    .fb_imageblit = cfb_imageblit, //图形填充

    .fb_open            = s702_lcd_open,
    .fb_release         = s702_lcd_release
    

    };
    {% endcodeblock %}

    • f.优化——加入延时机制:
      现在的程序基本完成,测试的时候,先加载backlight驱动insmod backlight_drv.ko,运行背光应用程序设置亮度./app 200
      然后加载LCD驱动insmod lcd_drv.ko,运行图片显示应用程序jpg_rgb显示图像./jpg_rgb cq.jpg,结果并没有显示图像,
      手动的echo on > /sys/devices/platform/11c00000.lcd_s702/power/control才正常显示图像。

    上述流程中,运行图片显示应用程序时,先open()了一次,引用计数加1,程序调用完又马上close,引用计数减1,导致看不到显示,
    重新操作/sys/devices/platform/11c00000.lcd_s702/power/control就立即显示了图像。

    对于正常的使用情景是,运行应用程序,立即图片显示,然后维持显示一段时间,如果有操作继续显示,没有的话再自己熄灭。
    因此,想要实现上面的功能,还需要加入自动休眠。

    在之前的probe()中加入pm_runtime_use_autosuspend():
    {% codeblock lang:c %}
    //Runtime
    pm_runtime_use_autosuspend(&pdev->dev);//add autosleep
    pm_runtime_set_autosuspend_delay(&pdev->dev, 5000);

    pm_runtime_set_active(&pdev->dev);
    pm_runtime_enable(&pdev->dev);
    

    {% endcodeblock %}

    同时,release()也要修改:
    {% codeblock lang:c %}
    static int s702_lcd_open(struct fb_info *info, int user)
    {
    struct device *dev = info->dev;
    int ret;

    printk("enter %s\n", __func__);
    
    ret = pm_runtime_get_sync(dev);
    if (ret < 0 && ret != -EACCES)
    {
        pm_runtime_put_sync(dev);
    
        return ret;
    }
    
    return 0;
    

    }
    static int s702_lcd_release(struct fb_info *info, int user)
    {
    struct device *dev = info->dev;

    printk("enter %s\n", __func__);
    
    //pm_runtime_put_sync(dev);
    pm_runtime_mark_last_busy(dev);
    pm_runtime_put_sync_autosuspend(dev);
    
    return 0;
    

    }
    {% endcodeblock %}

    此时,加载驱动后,运行应用程序,屏幕显示,5s后,屏幕自动熄灭,再次运行程序或者修改control来重新显示。

    通过函数pm_runtime_set_autosuspend_delay()或修改echo xx > /sys/devices/.../power/autosuspend_delay_ms来修改自动休眠时间。

    完整代码见Github

    4.regulator系统

    前面的两个电源管理模型偏“软”,regulator系统偏“硬”,
    在复杂的单板中,有专门的电源管理芯片控制各个模块电源,regulator系统就是为这个电源芯片编写驱动,实现电源管理。

    4.1 regulator框架

    ①Regulator(稳定器):指可以自动维持恒定电压(voltage)或电流(current)的装置,一般指电源芯片。在嵌入式设备中,基本上每一种电压,都是经过regulator输出的;
    ②③Consumer(使用者):使用电源的装置,Regulator是给Consumer供电的;
    ④Machine(单板):使用软件语言(struct regulator_init_data),静态的描述regulator在板级的物理现状,包含:
      a.级联关系:Regulator A的输出是Regulator B的输入,Regulator A就是Supply regulator,B是Consumer regulator
      b.约束限制:Regulator Constraints,比如电压/电流最大值/最小值、允许的操作等;

    从设备驱动的角度看,regulator系统比较简单,
    Machine提供Supply与Consumer的对应关系、单板相关的约束条件(device);
    Regulator提供电源芯片的控制函数,如使能/去能、设置电压/电流等(driver);
    Consumer调用Regulator相关函数控制电源的开关、调节(use);
    即一个描述关系,一个提供相关函数,一个调用相关函数。

    4.2 regulator流程

    4.3 regulator驱动

    regulator系统仍然是采用***总线设备驱动模型***。
    device采用c文件或设备树的形式,提供硬件相关信息;
    driver加载后,一但和device名字匹配,就调用probe()函数注册register,并绑定操作函数;

    后面将使用两种实现regulator驱动。
    这两种方式的核心都是一样的,
    device先提供Supply与Consumer的对应关系、单板相关的约束条件;
    driver提供电源芯片的控制函数,如使能/去能、设置电压/电流等。

    4.3.1 C文件方式

    #if 1

    static struct regulator_consumer_supply tiny4412_regulator_supplies[] =
    {
    REGULATOR_SUPPLY(“VCC_LCD”, “11c00000.lcd_s702”),//consumer的电源引脚名称;consumer的名字
    };

    #else

    static struct regulator_consumer_supply tiny4412_regulator_supplies[] =
    {
    REGULATOR_SUPPLY(“VCC_LCD”, “lcd_s702”),
    };

    #endif

    static struct regulator_init_data tiny4412_regulator_init_data =
    {
    .constraints = {
    //.name = “tiny4412_regulator”,
    .min_uV = 1000000,
    .max_uV = 1000000,
    .valid_modes_mask = REGULATOR_MODE_NORMAL,
    .valid_ops_mask = REGULATOR_CHANGE_STATUS,
    .boot_on = 0,
    .always_on = 0,
    },
    .num_consumer_supplies = 1,
    .consumer_supplies = tiny4412_regulator_supplies,
    };

    static void tiny4412_regulator_release(struct device *dev)
    {
    }

    static struct platform_device tiny4412_regulator_dev =
    {
    .name = “tiny4412_regulator”,
    .id = -1,
    .dev = {
    .release = tiny4412_regulator_release,
    .platform_data = &tiny4412_regulator_init_data,
    },
    };

    static int tiny4412_regulator_machine_init(void)
    {
    printk(“enter %s\n”, func);

    platform_device_register(&tiny4412_regulator_dev);
    return 0;
    

    }

    static void tiny4412_regulator_machine_exit(void)
    {
    printk(“enter %s\n”, func);

    platform_device_unregister(&tiny4412_regulator_dev);
    

    }

    module_init(tiny4412_regulator_machine_init);
    module_exit(tiny4412_regulator_machine_exit);

    MODULE_LICENSE(“GPL”);
    MODULE_AUTHOR(“hceng huangcheng.job@foxmail.com”);
    MODULE_DESCRIPTION(“Tiny4412 machine driver.”);
    MODULE_ALIAS(“Exynos4412_machine”);
    MODULE_VERSION(“V1.0”);
    {% endcodeblock %}

    static int regulator_states = 0;
    static int tiny4412_regulator_enable(struct regulator_dev *rdev)
    {
    printk(“enter %s\n”, func);

    printk("------LCD Power Open.------\n");
    regulator_states = 1;
    
    return 0;
    

    }

    static int tiny4412_regulator_disable(struct regulator_dev *rdev)
    {
    printk(“enter %s\n”, func);

    printk("------LCD Power Close.------\n");
    regulator_states = 0;
    
    return 0;
    

    }

    static int tiny4412_regulator_is_enabled(struct regulator_dev *rdev)
    {
    printk(“enter %s\n”, func);

    printk("------LCD Power Test.------\n");
    if (regulator_states)
        return 1;
    else
        return 0;
    

    }

    static struct regulator_ops tiny4412_regulator_ops =
    {
    .enable = tiny4412_regulator_enable,
    .disable = tiny4412_regulator_disable,
    .is_enabled = tiny4412_regulator_is_enabled,
    };

    static struct regulator_desc tiny4412_regulator_desc =
    {
    .name = “tiny4412_regulator”,
    .ops = &tiny4412_regulator_ops,
    .type = REGULATOR_VOLTAGE,//电压源
    .id = 0,
    .owner = THIS_MODULE,
    .n_voltages = 1,//能提供的电压数量
    };

    static struct regulator_dev *tiny4412_regulator_dev;
    static int tiny4412_regulator_probe(struct platform_device *pdev)
    {
    struct regulator_config config = { };
    config.dev = &pdev->dev;
    config.init_data = dev_get_platdata(&pdev->dev);

    printk("enter %s\n", __func__);
    
    tiny4412_regulator_dev = devm_regulator_register(&pdev->dev, &tiny4412_regulator_desc, &config);
    if (IS_ERR(tiny4412_regulator_dev))
    {
        printk("devm_regulator_register error!\n");
        return PTR_ERR(tiny4412_regulator_dev);
    }
    
    return 0;
    

    }

    static int tiny4412_regulator_remove(struct platform_device *pdev)
    {
    printk(“enter %s\n”, func);

    devm_regulator_unregister(&pdev->dev, tiny4412_regulator_dev);
    
    return 0;
    

    }

    struct platform_driver tiny4412_regulator_drv =
    {
    .probe = tiny4412_regulator_probe,
    .remove = tiny4412_regulator_remove,
    .driver = {
    .name = “tiny4412_regulator”,
    }
    };

    static int tiny4412_regulator_init(void)
    {
    printk(“enter %s\n”, func);

    platform_driver_register(&tiny4412_regulator_drv);
    return 0;
    

    }

    static void tiny4412_regulator_exit(void)
    {
    printk(“enter %s\n”, func);

    platform_driver_unregister(&tiny4412_regulator_drv);
    

    }

    module_init(tiny4412_regulator_init);
    module_exit(tiny4412_regulator_exit);

    MODULE_LICENSE(“GPL”);
    MODULE_AUTHOR(“hceng huangcheng.job@foxmail.com”);
    MODULE_DESCRIPTION(“Tiny4412 regulator driver.”);
    MODULE_ALIAS(“Exynos4412_regulator”);
    MODULE_VERSION(“V1.0”);
    {% endcodeblock %}

    • lcd_drv
      加载前面的machine.koregulator.ko,名字匹配后调用probe()注册regulator
      在LCD驱动中,若想使用regulator系统,需要先在LCD驱动的probe()根据名字获取对应regulator
        //regulator
        tiny4412_regulator = regulator_get(&pdev->dev, "VCC_LCD");
        if (IS_ERR(tiny4412_regulator))
        {
            printk("regulator_get error!\n");
            return -EIO;
        }
    

    再在suspend()resume()封面便调用regulator_disable()regulator_enable()

    此时,如果使用 系统睡眠模型Runtime电源模型 进行休眠操作,就会调用到regulator系统的操作函数,实现电源管理芯片的关闭。

    使用完后,释放regulator

    static int lcd_remove(struct platform_device *pdev)
    {
        //Direct Off: ENVID and ENVID_F are set to "0" simultaneously.
        unsigned int temp;
        
        temp = readl(lcd_regs_base + VIDCON0);
        temp &= ~(0x01 << 1 | 0x01 << 0);
        writel(temp, lcd_regs_base + VIDCON0);
    
        regulator_put(tiny4412_regulator);
    
        pm_runtime_disable(&pdev->dev);
    
        unregister_framebuffer(tiny4412_lcd);
        dma_free_writecombine(NULL, tiny4412_lcd->fix.smem_len, tiny4412_lcd->screen_base, tiny4412_lcd->fix.smem_start);
        framebuffer_release(tiny4412_lcd);
    
        return 0;
    }
    

    4.3.2 设备树方式

    与前面的操作几乎一样,只不过是在dts实现device

    • dts
      regulators节点下添加新的regulator,设置约束条件
    	regulators {
        		compatible = "simple-bus";
        		#address-cells = <1>;
        		#size-cells = <0>;
    
            mmc_reg: regulator@0{
    			compatible = "regulator-fixed";
    			reg = <0>;
    			regulator-name = "VMEM_VDD_2.8V";
    			regulator-min-microvolt = <2800000>;
    			regulator-max-microvolt = <2800000>;
    		}; 
    
            lcd_reg: regulator@1{
    			compatible = "tiny4412,lcd_regulator";
    			regulator-name = "VCC_LCD";
    			regulator-min-microvolt = <1200000>;
    			regulator-max-microvolt = <1200000>;
    		};
    	};
    

    在lcd节点下,添加级联关系

        lcd_s702@11C00000 {
            compatible = "tiny4412, lcd_s702";
            reg = <0x11C00000  0x20c0 0x10010210 0x08 0x10023c80 0x04 0x1003c000 0x1000>;
            pinctrl-names = "default";
            pinctrl-0 = <&lcd_s702>;
            clocks = <&clock CLK_FIMD0 &clock CLK_ACLK160>;
            clock-names = "fimd0","aclk160";
            vlcd-supply = <&lcd_reg>;
            status = "okay";
        }; 
    

    其中vlcd-supply与前面的regulator联系了起来。

    static int regulator_states = 0;
    static int tiny4412_regulator_enable(struct regulator_dev *rdev)
    {
    printk(“enter %s\n”, func);

    printk("------LCD Power Open.------\n");
    regulator_states = 1;
    
    return 0;
    

    }

    static int tiny4412_regulator_disable(struct regulator_dev *rdev)
    {
    printk(“enter %s\n”, func);

    printk("------LCD Power Close.------\n");
    regulator_states = 0;
    
    return 0;
    

    }

    static int tiny4412_regulator_is_enabled(struct regulator_dev *rdev)
    {
    printk(“enter %s\n”, func);

    printk("------LCD Power Test.------\n");
    if (regulator_states)
        return 1;
    else
        return 0;
    

    }

    static struct regulator_ops tiny4412_regulator_ops =
    {
    .enable = tiny4412_regulator_enable,
    .disable = tiny4412_regulator_disable,
    .is_enabled = tiny4412_regulator_is_enabled,
    };

    static struct regulator_desc tiny4412_regulator_desc =
    {
    .name = “tiny4412_regulator_dev”,
    .ops = &tiny4412_regulator_ops,
    .type = REGULATOR_VOLTAGE,//电压源
    .id = 0,
    .owner = THIS_MODULE,
    .n_voltages = 1,//能提供的电压数量
    };

    static struct regulator_dev *tiny4412_regulator_dev;
    static int tiny4412_regulator_probe(struct platform_device *pdev)
    {
    struct regulator_config config = { };
    config.dev = &pdev->dev;
    config.init_data = dev_get_platdata(&pdev->dev);

    printk("enter %s\n", __func__);
    
    tiny4412_regulator_dev = devm_regulator_register(&pdev->dev, &tiny4412_regulator_desc, &config);
    if (IS_ERR(tiny4412_regulator_dev))
    {
        printk("devm_regulator_register error!\n");
        return PTR_ERR(tiny4412_regulator_dev);
    }
    
    return 0;
    

    }

    static int tiny4412_regulator_remove(struct platform_device *pdev)
    {
    printk(“enter %s\n”, func);

    devm_regulator_unregister(&pdev->dev, tiny4412_regulator_dev);
    
    return 0;
    

    }

    static const struct of_device_id regulators_of_match[] =
    {
    { .compatible = “tiny4412,lcd_regulator” },
    { },
    };
    MODULE_DEVICE_TABLE(of, regulators_of_match);

    struct platform_driver tiny4412_regulator_drv =
    {
    .probe = tiny4412_regulator_probe,
    .remove = tiny4412_regulator_remove,
    .driver = {
    .name = “tiny4412_regulator_drv”,
    .of_match_table = of_match_ptr(regulators_of_match),
    }
    };

    static int tiny4412_regulator_init(void)
    {
    printk(“enter %s\n”, func);

    platform_driver_register(&tiny4412_regulator_drv);
    return 0;
    

    }

    static void tiny4412_regulator_exit(void)
    {
    printk(“enter %s\n”, func);

    platform_driver_unregister(&tiny4412_regulator_drv);
    

    }

    module_init(tiny4412_regulator_init);
    module_exit(tiny4412_regulator_exit);

    MODULE_LICENSE(“GPL”);
    MODULE_AUTHOR(“hceng huangcheng.job@foxmail.com”);
    MODULE_DESCRIPTION(“Tiny4412 regulator driver.”);
    MODULE_ALIAS(“Exynos4412_regulator”);
    MODULE_VERSION(“V1.0”);
    {% endcodeblock %}

    • lcd_drv
      和前面的使用完全一致。

    参考资料:
    韦东山第三期项目视频_电源管理
    蜗窝科技

    展开全文
  • [怎么看网卡设备]怎么查看网卡驱动问题:我的电脑连接不了网络,想看看...如果网卡驱动没有安装过的话,会显示?符号。如果网卡驱动有故障的话,会显示感叹号!。如果出现以上2个提示的话,就请重新安装网卡驱动,安...
  • 电脑无线网卡中的选项详解

    千次阅读 2014-01-17 11:41:44
    Ad Hoc QoS 模式 Ad hoc 网络中的服务质量 (QoS) 控制。QoS 根据无线网络上接入点的通信量提供通信量分类优先化。WMM (Wi-Fi Multimedia) 是 Wi-Fi Alliance (WFA) 的 QoS 认证。...Ad Hoc 电源管理
  • 注意:英特尔快速存储技术中的链接电源管理 (LPM) 是一项节能技术;它能帮助 SATA 设备节省能耗。与设备的 SATA 链接在没有 I/O 活动或设备不存在或不使用的闲置时段内被设为低能耗。LPM 在需要工作而在链接上有 I/O...
  • Windows CE设备驱动开发之电源管理

    千次阅读 2012-06-02 16:28:33
    4.7电源管理 电源管理模块管理设备电源,从而全面改进操作系统的电源使用效率;它所有设备的电源使用,同时能与不支持电源管理的应用程序及驱动程序共存。 使用电源管理可以有效的减少目标设备的电源消耗,同时,...
  • 为了节省能源,电脑普遍都有省电设计。在一段时间没有使用时,电脑可...若要完全发挥电源管理功能,除了需要正确设置和选择这里介绍的有关参数外,还必需有相关硬件外设配合,BIOS的电源管理界面如图1所示: 图 1
  • 您可以从设备管理器配置这些设置。右键单击设备,然后选择“属性”。注意1由管理员该帖子已被编辑。...允许计算机关闭此设备以节省电量在电源管理选项卡中,您必须启用允许计算机关闭此设备以节省电力,并且Wind...
  • Acer Epower Management是宏碁为笔记本用户开发的电源管理软件。
  • Linux内核配置电源管理

    千次阅读 2015-06-15 11:16:22
    最近测试板子辐射比较高,希望...//如果你想让你的Linux支持高级电源管理(也就是平常我们说的软关机、系统休眠等)需要选择它   [ ] Power Management Debug Support //不想调试ACPI,不选 [*] Suspend to RAM an
  • 应该是网卡电源管理策略的问题 1.3. 解决方案 进入网卡配置界面,选择“电源管理”选项栏 这里如果没有“电源管理”这一选项栏,首先升级你的网卡驱动 勾选“允许”计算机关闭此设备以节约电源 问题即解决 1.4. 疑问...
  • Linux的电源管理架构

    千次阅读 2013-04-12 15:59:26
    转一个和休眠有关的,这部分打算深入学习! 转自:... Linux的电源管理架构 来自 Fgamers 2011年 8月 25日 3,288 次阅读 评论 (1) ************
  • Linux笔记本电源管理指南

    千次阅读 2012-09-19 16:49:14
    找了很久的东西,希望对大家有用,自己也在为不能关机的事情...我们知道,笔记本受到电池续航时间的限制,所以特别注重机器的电源管理。因此,本文将讨论如何处理这些事项。 一、概述 实际上,除了利用主板上的
  • 故障描述:Y450笔记本,无法通过无线网卡连接到网络,无线网卡灯指示灯熄灭,物理开关已经开启,快捷键开关开启后,Lenovo无线装置设定的界面没有无线网卡选项,只有蓝牙的选项(参考图1)(图1)原因分析:笔记本在...
  • Linux的源代码里,大部分都属于设备驱动程序的代码,因此,大多数电源管理(PM)的代码也是存在于驱动程序当中。很多驱动程序可能只做了少量的工作,另外一些,例如使用电池供电的硬件平台(移动电话等)则会在电源管理...
  • https://blog.csdn.net/weixin_44745717/article/details/100144347 Ubuntu下的无线一直断线重连, 不知道是不是电源的问题,先关闭再看情况吧
  • Linux的源代码里,大部分都属于设备驱动程序的代码,因此,大多数电源管理(PM)的代码也是存在于驱动程序当中。很多驱动程序可能只做了少量的工作,另外一些,例如使用电池供电的硬件平台(移动电话等)则会在电源...
  • 转自: ...   设备电源管理 Copyright (c) 2010 Rafael J. Wysocki, Novell Inc. Copyright (c) 2010 Alan Sternstern@rowland.harvard.edu *********************
  • 我的台式机一开机无线网卡就会自动禁用了,该怎么办呢?下面由学习啦小编给你...方案:右键我的电脑,点击设备管理器,展开网络适配器,找到无线网卡驱动(里面含wireless单词的),如下图:可能禁用了无线WLAN Auto...
  • 今天公司出现了三台海尔博越M53无线网卡如上报错,似乎在报错的时候不会给出电源管理选项。建议先卸载硬件,然后重启电脑,这时候硬件应该又正常运行了再进行以下操作。 按照以下操作: 1.按住win键,输入...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,062
精华内容 4,424
关键字:

网卡没有电源管理选项