mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
rk31:linux3.10:support io domain setting by regulator
This commit is contained in:
@@ -763,6 +763,87 @@
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_LCDC1_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_DEFAULT>;
|
||||
};
|
||||
|
||||
ap0_vcc_18:ap0-vcc-18 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_AP0_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_1V8>;
|
||||
};
|
||||
|
||||
ap1_vcc_18:ap1-vcc-18 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_AP1_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_1V8>;
|
||||
};
|
||||
|
||||
cif_vcc_18:cif-vcc-18 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_CIF_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_1V8>;
|
||||
};
|
||||
|
||||
flash_vcc_18:flash-vcc-18 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_FLASH_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_1V8>;
|
||||
};
|
||||
|
||||
vccio0_vcc_18:vccio0-vcc-18 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_VCCIO0_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_1V8>;
|
||||
};
|
||||
|
||||
vccio1_vcc_18:vccio1-vcc-18 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_VCCIO1_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_1V8>;
|
||||
};
|
||||
|
||||
lcdc0_vcc_18:lcdc0-vcc-18 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_LCDC0_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_1V8>;
|
||||
};
|
||||
|
||||
lcdc1_vcc_18:lcdc1-vcc-18 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_LCDC1_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_1V8>;
|
||||
};
|
||||
|
||||
ap0_vcc_33:ap0-vcc-33 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_AP0_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_3V3>;
|
||||
};
|
||||
|
||||
ap1_vcc_33:ap1-vcc-33 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_AP1_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_3V3>;
|
||||
};
|
||||
|
||||
cif_vcc_33:cif-vcc-33 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_CIF_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_3V3>;
|
||||
};
|
||||
|
||||
flash_vcc_33:flash-vcc-33 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_FLASH_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_3V3>;
|
||||
};
|
||||
|
||||
vccio0_vcc_33:vccio0-vcc-33 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_VCCIO0_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_3V3>;
|
||||
};
|
||||
|
||||
vccio1_vcc_33:vccio1-vcc-33 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_VCCIO1_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_3V3>;
|
||||
};
|
||||
|
||||
lcdc0_vcc_33:lcdc0-vcc-33 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_LCDC0_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_3V3>;
|
||||
};
|
||||
|
||||
lcdc1_vcc_33:lcdc1-vcc-33 {
|
||||
rockchip,pins = <VIRTUAL_PIN_FOR_LCDC1_VCC>;
|
||||
rockchip,voltage = <VALUE_VOL_3V3>;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
9
arch/arm/boot/dts/rk3188-tb.dts
Executable file → Normal file
9
arch/arm/boot/dts/rk3188-tb.dts
Executable file → Normal file
@@ -5,6 +5,7 @@
|
||||
#include "lcd-b101ew05.dtsi"
|
||||
#include "rk3188-mmc.dtsi"
|
||||
|
||||
|
||||
/ {
|
||||
memory {
|
||||
device_type = "memory";
|
||||
@@ -279,8 +280,8 @@ regulators {
|
||||
};
|
||||
|
||||
dcdc4_reg: regulator@3 {
|
||||
regulator-name= "act_dcdc4";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-name= "vccio";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
@@ -378,8 +379,8 @@ regulators {
|
||||
};
|
||||
|
||||
rk808_dcdc4_reg: regulator@3 {
|
||||
regulator-name= "rk_dcdc4";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-name= "vccio";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "skeleton.dtsi"
|
||||
#include "rk3188-pinctrl.dtsi"
|
||||
#include <dt-bindings/rkfb/rk_fb.h>
|
||||
#include "rk3188_io_vol_domain.dtsi"
|
||||
|
||||
|
||||
/ {
|
||||
|
||||
76
arch/arm/boot/dts/rk3188_io_vol_domain.dtsi
Normal file
76
arch/arm/boot/dts/rk3188_io_vol_domain.dtsi
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
/ {
|
||||
|
||||
vccio{
|
||||
compatible = "rockchip,io_vol_domain";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pinctrl-names = "default", "1.8V", "3.3V";
|
||||
pinctrl-0 = <&ap1_vcc &vccio0_vcc &vccio1_vcc &lcdc1_vcc>;
|
||||
pinctrl-1 = <&ap1_vcc_18 &vccio0_vcc_18 &vccio1_vcc_18 &lcdc1_vcc_18>;
|
||||
pinctrl-2 = <&ap1_vcc_33 &vccio0_vcc_33 &vccio1_vcc_33 &lcdc1_vcc_33>;
|
||||
|
||||
regulator_name{
|
||||
regulator-name= "vccio";
|
||||
};
|
||||
};
|
||||
vccio_wl{
|
||||
compatible = "rockchip,io_vol_domain";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pinctrl-names = "default", "1.8V", "3.3V";
|
||||
pinctrl-0 = <&ap0_vcc>;
|
||||
pinctrl-1 = <&ap0_vcc_18>;
|
||||
pinctrl-2 = <&ap0_vcc_33>;
|
||||
|
||||
regulator_name{
|
||||
regulator-name= "vccio_wl";
|
||||
};
|
||||
};
|
||||
vcc18_cif{
|
||||
compatible = "rockchip,io_vol_domain";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pinctrl-names = "default", "1.8V", "3.3V";
|
||||
pinctrl-0 = <&cif_vcc>;
|
||||
pinctrl-1 = <&cif_vcc_18>;
|
||||
pinctrl-2 = <&cif_vcc_33>;
|
||||
|
||||
regulator_name{
|
||||
regulator-name= "vcc18_cif";
|
||||
};
|
||||
};
|
||||
vcc_flash{
|
||||
compatible = "rockchip,io_vol_domain";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pinctrl-names = "default", "1.8V", "3.3V";
|
||||
pinctrl-0 = <&flash_vcc>;
|
||||
pinctrl-1 = <&flash_vcc_18>;
|
||||
pinctrl-2 = <&flash_vcc_33>;
|
||||
|
||||
regulator_name{
|
||||
regulator-name= "vcc_flash";
|
||||
};
|
||||
};
|
||||
vcc_lcd{
|
||||
compatible = "rockchip,io_vol_domain";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pinctrl-names = "default", "1.8V", "3.3V";
|
||||
pinctrl-0 = <&lcdc0_vcc>;
|
||||
pinctrl-1 = <&lcdc0_vcc_18>;
|
||||
pinctrl-2 = <&lcdc0_vcc_33>;
|
||||
|
||||
regulator_name{
|
||||
regulator-name= "vcc_lcd";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -72,5 +72,7 @@ obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_ACT8846) += act8846.o
|
||||
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rk_io_vol_domain.o
|
||||
|
||||
|
||||
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
|
||||
|
||||
192
drivers/regulator/rk_io_vol_domain.c
Normal file
192
drivers/regulator/rk_io_vol_domain.c
Normal file
@@ -0,0 +1,192 @@
|
||||
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/regulator/rk_io_vol_domain.h>
|
||||
|
||||
struct io_domain_port *g_uap;
|
||||
|
||||
int io_domain_regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
|
||||
{
|
||||
int old_voltage,ret =0;
|
||||
|
||||
old_voltage = io_domain_regulator_get_voltage(regulator);
|
||||
if (IS_ERR(g_uap->pins_3v3) ||IS_ERR(g_uap->pins_1v8) ){
|
||||
printk("IO_DOMAIN:ERROR:The io vol domin is not exit. %s\n",__func__);
|
||||
}
|
||||
|
||||
if (min_uV >= old_voltage){
|
||||
if( min_uV > IO_VOL_DOMAIN_3V3){
|
||||
pinctrl_select_state(g_uap->pctl, g_uap->pins_3v3);
|
||||
IO_DOMAIN_DBG("IO_DOMAIN:set io domain 3.3v. %s \n",__func__);
|
||||
}
|
||||
else if (min_uV > IO_VOL_DOMAIN_1V8){
|
||||
pinctrl_select_state(g_uap->pctl, g_uap->pins_1v8);
|
||||
IO_DOMAIN_DBG("IO_DOMAIN:set io domain 1.8v. %s \n",__func__);
|
||||
}
|
||||
ret = regulator_set_voltage(regulator,min_uV,max_uV);
|
||||
}
|
||||
else if (min_uV < old_voltage){
|
||||
ret = regulator_set_voltage(regulator,min_uV,max_uV);
|
||||
if( min_uV > IO_VOL_DOMAIN_3V3){
|
||||
pinctrl_select_state(g_uap->pctl, g_uap->pins_3v3);
|
||||
IO_DOMAIN_DBG("IO_DOMAIN:set io domain 3.3v. %s \n",__func__);
|
||||
}
|
||||
else if (min_uV > IO_VOL_DOMAIN_1V8){
|
||||
pinctrl_select_state(g_uap->pctl, g_uap->pins_1v8);
|
||||
IO_DOMAIN_DBG("IO_DOMAIN:set io domain 1.8v. %s \n",__func__);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_PM)
|
||||
static int rk_io_vol_domain_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk_io_vol_domain_resume(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define rk_io_vol_domain_suspend NULL
|
||||
#define rk_io_vol_domain_resume NULL
|
||||
#endif
|
||||
|
||||
static int rk_io_vol_domain_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct io_domain_port *uap;
|
||||
struct vd_node *vd;
|
||||
struct device_node *io_domain_node,*pd_dev_node ;
|
||||
struct regulator *vol_regulator;
|
||||
struct io_domain_device *io_vol_dev = NULL;
|
||||
int vol=0,ret =0;
|
||||
|
||||
io_vol_dev = devm_kzalloc(&pdev->dev, sizeof(struct io_domain_device), GFP_KERNEL);
|
||||
if (!io_vol_dev) {
|
||||
dev_err(&pdev->dev, "no memory for state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
platform_set_drvdata(pdev, io_vol_dev);
|
||||
io_vol_dev->dev = &pdev->dev;
|
||||
|
||||
uap = devm_kzalloc(&pdev->dev, sizeof(struct io_domain_port),
|
||||
GFP_KERNEL);
|
||||
if (uap == NULL) {
|
||||
printk("uap is not set %s,line=%d\n", __func__,__LINE__);
|
||||
|
||||
}
|
||||
uap->pctl = devm_pinctrl_get(io_vol_dev->dev);
|
||||
uap->pins_default = pinctrl_lookup_state(uap->pctl,"default");
|
||||
uap->pins_1v8 = pinctrl_lookup_state(uap->pctl, "1.8V");
|
||||
uap->pins_3v3 = pinctrl_lookup_state(uap->pctl,"3.3V");
|
||||
g_uap = uap;
|
||||
|
||||
io_domain_node = of_node_get(pdev->dev.of_node);
|
||||
if (!io_domain_node) {
|
||||
printk("could not find rk_io_vol_domain-node\n");
|
||||
return -ENOMEM ;
|
||||
}
|
||||
|
||||
for_each_available_child_of_node(io_domain_node,pd_dev_node) {
|
||||
vd = kzalloc(sizeof(struct vd_node), GFP_KERNEL);
|
||||
if (!vd)
|
||||
return -ENOMEM;
|
||||
|
||||
vd->name = pd_dev_node->name;
|
||||
pd_dev_node->name = of_get_property(pd_dev_node, "regulator-name", NULL);
|
||||
if (pd_dev_node->name== NULL) {
|
||||
printk("%s vd(%s) pd_dev_node->name(%s) get regulator_name err, ret:%d\n",
|
||||
__func__,vd->name , pd_dev_node->name,ret);
|
||||
kfree(vd);
|
||||
continue;
|
||||
}
|
||||
vol_regulator = regulator_get(NULL,pd_dev_node->name);
|
||||
if (IS_ERR(vol_regulator)){
|
||||
pinctrl_select_state(uap->pctl, uap->pins_default);
|
||||
IO_DOMAIN_DBG("IO_DOMAIN:ERROR:The io vol domin is not exit,set it by defult. %s %s\n",__func__,pd_dev_node->name);
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
vol = regulator_get_voltage(vol_regulator);
|
||||
if (vol > IO_VOL_DOMAIN_3V3){
|
||||
pinctrl_select_state(uap->pctl, uap->pins_3v3);
|
||||
IO_DOMAIN_DBG("IO_DOMAIN:set io domain 3.3v. %s %s = %d\n",__func__,pd_dev_node->name,vol);
|
||||
}
|
||||
else if (vol > IO_VOL_DOMAIN_1V8){
|
||||
pinctrl_select_state(uap->pctl, uap->pins_1v8);
|
||||
IO_DOMAIN_DBG("IO_DOMAIN:set io domain 1.8v. %s %s = %d\n",__func__,pd_dev_node->name,vol);
|
||||
}
|
||||
else{
|
||||
pinctrl_select_state(uap->pctl, uap->pins_default);
|
||||
IO_DOMAIN_DBG("IO_DOMAIN:ERROR:The io vol domin is not exit,set it by defult. %s %s\n",__func__,pd_dev_node->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk_io_vol_domain_remove(struct platform_device *pdev)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id rk_io_vol_domain_dt_ids[] = {
|
||||
{.compatible = "rockchip,io_vol_domain", .data = NULL, },
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct platform_driver rk_io_vol_domain_driver = {
|
||||
.probe = rk_io_vol_domain_probe,
|
||||
.remove = rk_io_vol_domain_remove,
|
||||
.driver = {
|
||||
.name = "rk_io_vol_domain",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(rk_io_vol_domain_dt_ids),
|
||||
},
|
||||
.suspend = rk_io_vol_domain_suspend,
|
||||
.resume = rk_io_vol_domain_resume,
|
||||
};
|
||||
|
||||
static int __init rk_io_vol_domain_module_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk_io_vol_domain_driver);
|
||||
}
|
||||
|
||||
static void __exit rk_io_vol_domain_module_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk_io_vol_domain_driver);
|
||||
}
|
||||
|
||||
fs_initcall(rk_io_vol_domain_module_init);
|
||||
module_exit(rk_io_vol_domain_module_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("rockchip");
|
||||
MODULE_DESCRIPTION("rk io domain setting");
|
||||
|
||||
|
||||
51
include/linux/regulator/rk_io_vol_domain.h
Executable file
51
include/linux/regulator/rk_io_vol_domain.h
Executable file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 2014 ROCKCHIP, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
|
||||
#if 0
|
||||
#define IO_DOMAIN_DBG(fmt, args...) printk( "IO_DOMAIN_DBG:\t"fmt, ##args)
|
||||
#else
|
||||
#define IO_DOMAIN_DBG(fmt, args...) {while(0);}
|
||||
#endif
|
||||
|
||||
#define io_domain_regulator_get(dev,id) regulator_get((dev),(id))
|
||||
#define io_domain_regulator_put(regu) regulator_put((regu))
|
||||
#define io_domain_regulator_get_voltage(regu) regulator_get_voltage((regu))
|
||||
|
||||
int io_domain_regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
|
||||
|
||||
#define IO_VOL_DOMAIN_3V3 2800000
|
||||
#define IO_VOL_DOMAIN_1V8 1500000
|
||||
|
||||
struct vd_node {
|
||||
const char *name;
|
||||
const char *regulator_name;
|
||||
struct regulator *regulator;
|
||||
struct list_head node;
|
||||
};
|
||||
struct io_domain_port {
|
||||
struct pinctrl *pctl;
|
||||
struct pinctrl_state *pins_default;
|
||||
struct pinctrl_state *pins_1v8;
|
||||
struct pinctrl_state *pins_3v3;
|
||||
};
|
||||
|
||||
struct io_domain_device{
|
||||
struct device *dev;
|
||||
struct device_node *of_node;
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user