linux3.10:pwm:support pwm set voltage by regulator
author张晴 <zhangqing@rock-chips.com>
Fri, 14 Mar 2014 10:14:56 +0000 (18:14 +0800)
committer张晴 <zhangqing@rock-chips.com>
Fri, 14 Mar 2014 10:14:56 +0000 (18:14 +0800)
arch/arm/boot/dts/rk3188-tb.dts [changed mode: 0644->0755]
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/rk30-pwm-regulator.c
include/linux/regulator/rk29-pwm-regulator.h

old mode 100644 (file)
new mode 100755 (executable)
index 87ebb1a..fb1c5f0
                enable-gpios = <&gpio0 GPIO_A2 GPIO_ACTIVE_HIGH>;
        };
 
+       pwm_regulator {
+       compatible = "rockchip_pwm_regulator";
+       pwms = <&pwm0 0 25000>;
+       rockchip,pwm_id= <0>;
+       rockchip,pwm_voltage_map= <925000 950000 975000 1000000 1025000 1050000 1075000 1100000 1125000 1150000 1175000 1200000 1225000 1250000 1275000 1300000 1325000 1350000 1375000 1400000>;
+       rockchip,pwm_voltage= <1000000>;
+       rockchip,pwm_min_voltage= <925000>;
+       rockchip,pwm_max_voltage= <1400000>;
+       rockchip,pwm_suspend_voltage= <950000>;
+       rockchip,pwm_coefficient= <475>;
+       regulators {
+               #address-cells = <1>;
+               #size-cells = <0>;                      
+                pwm_reg0: regulator@0{
+                       regulator-compatible = "pwm_dcdc1";
+                       regulator-name= "vdd_gpu";
+                       regulator-min-microvolt = <925000>;
+                       regulator-max-microvolt = <1400000>;    
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+           };
+       };
+
+
        codec_hdmi_i2s: codec-hdmi-i2s {
                compatible = "hdmi-i2s";
        };
        status = "okay";
 };
 
+&pwm0 {
+        status = "disable";
+};
+
 &clk_core_dvfs_table {
        operating-points = <
                /* KHz    uV */
index 3d074b03a8fb972253724944b7a004b724598258..0788f8470dd1d29c851d5c6e1b8d9d2d9de4ccb0 100644 (file)
@@ -262,6 +262,11 @@ config ACT8846_SUPPORT_RESET
        help
          Support short press key to restart.
 
+config RK30_PWM_REGULATOR
+       tristate "rk30 pwm voltage regulator for discrete dcdc or ldo"
+       help
+         Say Y to enable support for the voltage regulators control on the RK30 .
+
 config REGULATOR_PCAP
        tristate "Motorola PCAP2 regulator driver"
        depends on EZX_PCAP
index 8106b9f2c794bf3c9f90ec769221b89191710294..bc1815fd5672ebc9d6c2bccc572cb46ca25516a3 100644 (file)
@@ -51,6 +51,9 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
 obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
+
+obj-$(CONFIG_RK30_PWM_REGULATOR) += rk30-pwm-regulator.o
+
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
index 6ebb98c20805c1461cbad45016c732f7187c6bf5..4de209ac31705df12a6eb76d554fbb62cc07a948 100755 (executable)
 #include <asm/io.h>\r
 #include <linux/delay.h>\r
 #include <linux/slab.h>\r
-#include <linux/regulator/driver.h>\r
 #include <linux/regulator/rk29-pwm-regulator.h>\r
-#include <mach/iomux.h>\r
-#include <linux/gpio.h>\r
-#include <mach/board.h>\r
-#include <plat/pwm.h>\r
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/module.h>\r
+#include <linux/init.h>
+#include <linux/err.h>\r
+#include <linux/pwm.h>\r
+\r
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regulator/of_regulator.h>\r
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+\r
 \r
-#if 0\r
+#if 1\r
 #define DBG(x...)      printk(KERN_INFO x)\r
 #else\r
 #define DBG(x...)\r
 #endif\r
 \r
-struct rk_pwm_dcdc {\r
-        char name[16];\r
-        struct regulator_desc desc;\r
-        int pwm_id;\r
-        struct clk *pwm_clk;\r
-        const void __iomem *pwm_base;\r
-        u32 suspend_hrc;\r
-        u32 suspend_lrc;\r
-        u32 backup_hrc;\r
-        u32 backup_lrc;\r
-        struct regulator_dev *regulator;\r
-       struct pwm_platform_data *pdata;\r
-};\r
-\r
-#if defined(CONFIG_SOC_RK3168) || defined(CONFIG_SOC_RK3168M) || defined(CONFIG_ARCH_RK3188) || defined(CONFIG_ARCH_RK3026)\r
 const static int pwm_voltage_map[] = {\r
-       800000,825000,850000, 875000,900000, 925000 ,950000, 975000,1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000,1375000\r
+       925000 ,950000, 975000,1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000,1375000,1400000\r
 };\r
-#else\r
-const static int pwm_voltage_map[] = {\r
-       950000, 975000,1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000\r
-};\r
-#endif\r
-\r
-static struct rk_pwm_dcdc *g_dcdc;\r
-\r
-static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)\r
-{\r
-       u32 lrc, hrc;\r
-       int id = pdata->pwm_id;\r
-       unsigned long clkrate;\r
-\r
-       clkrate = clk_get_rate(g_dcdc->pwm_clk);\r
        \r
-       DBG("%s:id=%d,rate=%d,clkrate=%d\n",__func__,id,rate,clkrate); \r
-\r
-       if(rate == 0)\r
-       {\r
-               // iomux pwm to gpio\r
-               rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_gpio);\r
-               //disable pull up or down\r
-               gpio_pull_updown(pdata->pwm_gpio,PullDisable);\r
-               // set gpio to low level\r
-               gpio_direction_output(pdata->pwm_gpio,GPIO_LOW);\r
-       }\r
-       else if (rate < 100)\r
-       {\r
-               lrc = clkrate / nHz;\r
-               lrc = lrc >> (1+(PWM_DIV>>9));\r
-               lrc = lrc ? lrc : 1;\r
-               hrc = lrc * rate / 100;\r
-               hrc = hrc ? hrc : 1;\r
-\r
-               // iomux pwm\r
-               rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_pwm);\r
+static struct pwm_platform_data *g_pdata;\r
 \r
-               rk_pwm_setup(id, PWM_DIV, hrc, lrc);\r
-       }\r
-       else if (rate == 100)\r
-       {\r
-               // iomux pwm to gpio\r
-               rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_gpio);\r
-               //disable pull up or down\r
-               gpio_pull_updown(pdata->pwm_gpio,PullDisable);\r
-               // set gpio to low level\r
-               gpio_direction_output(pdata->pwm_gpio,GPIO_HIGH);\r
+static int pwm_set_rate(struct pwm_platform_data *pdata,u32 rate)\r
+{\r
+       int duty_cycle;\r
+       DBG("%s:id=%d,rate=%d clkrate =%d\n",__func__,pdata->pwm_id,rate,pdata->period); \r
 \r
-       }\r
-       else\r
-       {\r
-               printk("%s:rate error\n",__func__);\r
-               return -1;\r
-       }\r
+       duty_cycle = (rate * (pdata->period ) / 100) ;\r
 \r
+       pwm_config(pdata->pwm, duty_cycle, pdata->period);\r
+       \r
        usleep_range(10*1000, 10*1000);\r
 \r
        return (0);\r
@@ -114,9 +63,8 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)
 \r
 static int pwm_regulator_list_voltage(struct regulator_dev *dev,unsigned int index)\r
 {\r
-       struct rk_pwm_dcdc *dcdc = rdev_get_drvdata(dev);\r
-       if (index < dcdc->desc.n_voltages)\r
-       return dcdc->pdata->pwm_voltage_map[index];\r
+       if (index <( g_pdata->pwm_vol_map_count +1))\r
+       return g_pdata->pwm_voltage_map[index];\r
        else\r
                return -1;\r
 }\r
@@ -140,30 +88,30 @@ static int pwm_regulator_disable(struct regulator_dev *dev)
 }\r
 \r
 static int pwm_regulator_get_voltage(struct regulator_dev *dev)\r
-{\r
-       //struct pwm_platform_data *pdata = rdev_get_drvdata(dev);\r
-       \r
-       struct rk_pwm_dcdc *dcdc = rdev_get_drvdata(dev);\r
+{      \r
+       u32 vol;\r
 \r
        DBG("Enter %s\n",__FUNCTION__);  \r
 \r
-       return (dcdc->pdata->pwm_voltage);\r
+       vol = g_pdata->pwm_voltage;\r
+\r
+       return vol;\r
 }\r
 \r
 static int pwm_regulator_set_voltage(struct regulator_dev *dev,\r
                int min_uV, int max_uV, unsigned *selector)\r
 {         \r
-       struct rk_pwm_dcdc *dcdc = rdev_get_drvdata(dev);\r
-       const int *voltage_map = dcdc->pdata->pwm_voltage_map;\r
-       int max = dcdc->pdata->max_uV;\r
-       int coefficient = dcdc->pdata->coefficient;\r
-       u32 size = dcdc->desc.n_voltages, i, vol,pwm_value;\r
+       const int *voltage_map = g_pdata->pwm_voltage_map;\r
+       int max = g_pdata->max_uV;\r
+       int coefficient = g_pdata->coefficient;\r
+       u32 size = g_pdata->pwm_vol_map_count;\r
+       u32 i, vol,pwm_value;\r
 \r
-       DBG("%s:  min_uV = %d, max_uV = %d\n",__FUNCTION__, min_uV,max_uV);\r
+       DBG("%s:  min_uV = %d, max_uV = %d \n",__FUNCTION__, min_uV,max_uV);\r
 \r
-       if (min_uV < voltage_map[0] ||max_uV > voltage_map[size-1])\r
+       if (min_uV < voltage_map[0] ||max_uV > voltage_map[size])\r
        {\r
-               printk("%s:voltage is out of table\n",__func__);\r
+               printk("%s: voltage_map voltage is out of table\n",__func__);\r
                return -EINVAL;\r
        }\r
 \r
@@ -172,25 +120,21 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev,
                if (voltage_map[i] >= min_uV)\r
                        break;\r
        }\r
-\r
-\r
        vol =  voltage_map[i];\r
-\r
-       dcdc->pdata->pwm_voltage = vol;\r
+       g_pdata->pwm_voltage = vol;\r
 \r
        // VDD12 = 1.40 - 0.455*D , ÆäÖÐDΪPWMÕ¼¿Õ±È, \r
        pwm_value = (max-vol)/coefficient/10;  // pwm_value %, coefficient *1000\r
 \r
-       if (pwm_set_rate(dcdc->pdata,1000*1000,pwm_value)!=0)\r
+       if (pwm_set_rate(g_pdata,pwm_value)!=0)\r
        {\r
                printk("%s:fail to set pwm rate,pwm_value=%d\n",__func__,pwm_value);\r
                return -1;\r
 \r
        }\r
-\r
        *selector = i;\r
 \r
-       DBG("%s:ok,vol=%d,pwm_value=%d\n",__FUNCTION__,vol,pwm_value);\r
+       DBG("%s:ok,vol=%d,pwm_value=%d %d\n",__FUNCTION__,vol,pwm_value,g_pdata->pwm_voltage);\r
 \r
        return 0;\r
 \r
@@ -204,105 +148,234 @@ static struct regulator_ops pwm_voltage_ops = {
        .disable        = pwm_regulator_disable,\r
        .is_enabled     = pwm_regulator_is_enabled,\r
 };\r
+static struct regulator_desc regulators[] = {\r
+\r
+        {\r
+               .name = "PWM_DCDC1",\r
+               .id = 0,\r
+               .ops = &pwm_voltage_ops,\r
+               .n_voltages =  ARRAY_SIZE(pwm_voltage_map),\r
+               .type = REGULATOR_VOLTAGE,\r
+               .owner = THIS_MODULE,\r
+       },\r
+};\r
 \r
-static int __devinit pwm_regulator_probe(struct platform_device *pdev)\r
-{\r
-       struct pwm_platform_data *pdata = pdev->dev.platform_data;\r
-       struct rk_pwm_dcdc *dcdc;\r
-       int pwm_id  =  pdata->pwm_id;\r
-       int id = pdev->id;\r
-       int ret ;\r
-       char gpio_name[20];\r
-       unsigned selector = 0;\r
-       \r
-       if (!pdata)\r
-               return -ENODEV;\r
-\r
-       if (!pdata->pwm_voltage)\r
-               pdata->pwm_voltage = 1100000;   // default 1.1v\r
-\r
-       if(!pdata->pwm_voltage_map)\r
-               pdata->pwm_voltage_map = pwm_voltage_map;\r
+#ifdef CONFIG_OF
+static struct of_device_id pwm_of_match[] = {\r
+       { .compatible = "rockchip_pwm_regulator"},\r
+       { },
+};
+MODULE_DEVICE_TABLE(of, pwm_of_match);\r
 \r
-       if(!pdata->max_uV)\r
-               pdata->max_uV = 1400000;\r
+static struct of_regulator_match pwm_matches[] = {\r
+       { .name = "pwm_dcdc1",  .driver_data = (void *)0  },\r
+};\r
 \r
-       if(!pdata->min_uV)\r
-               pdata->min_uV = 1000000;\r
+static struct pwm_regulator_board *pwm_regulator_parse_dt(\r
+               struct platform_device *pdev,
+               struct of_regulator_match **pwm_reg_matches)\r
+{
+       struct pwm_regulator_board *pwm_plat_data;\r
+       struct device_node *np, *regulators;\r
+       struct of_regulator_match *matches;
+       int idx = 0, ret, count;\r
+       struct property *prop;\r
+       int length;\r
+       const __be32 *init_vol, *max_vol,*min_vol,*suspend_vol,*coefficient,*id;\r
        \r
-       if(pdata->suspend_voltage < pdata->min_uV)\r
-               pdata->suspend_voltage = pdata->min_uV;\r
+        DBG("%s,line=%d\n", __func__,__LINE__);\r
+
+       pwm_plat_data = devm_kzalloc(&pdev->dev, sizeof(*pwm_plat_data),\r
+                                       GFP_KERNEL);
+
+       if (!pwm_plat_data) {\r
+               dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n");
+               return NULL;
+       }
+\r
+       np = of_node_get(pdev->dev.of_node);\r
+       regulators = of_find_node_by_name(np, "regulators");
+       if (!regulators) {
+               dev_err(&pdev->dev, "regulator node not found\n");
+               return NULL;
+       }
+       count = ARRAY_SIZE(pwm_matches);\r
+       matches = pwm_matches;  \r
+       ret = of_regulator_match(&pdev->dev, regulators, matches, count);
+       of_node_put(regulators);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
+                       ret);
+               return NULL;
+       }\r
        \r
-       if(pdata->suspend_voltage > pdata->max_uV)      \r
-               pdata->suspend_voltage = pdata->max_uV;\r
+       pwm_plat_data ->num_regulators = count;\r
+       *pwm_reg_matches = matches;\r
        \r
-       dcdc = kzalloc(sizeof(struct rk_pwm_dcdc), GFP_KERNEL);\r
-       if (dcdc == NULL) {\r
-               dev_err(&pdev->dev, "Unable to allocate private data\n");\r
-               return -ENOMEM;\r
+       for (idx = 0; idx < count; idx++) {
+               if (!matches[idx].init_data || !matches[idx].of_node)
+                       continue;\r
+               pwm_plat_data->pwm_init_data[idx] =matches[idx].init_data;\r
+               pwm_plat_data->of_node[idx]=matches[idx].of_node;\r
        }\r
+       \r
+       init_vol = of_get_property(np, "rockchip,pwm_voltage", NULL);\r
+       if (init_vol)\r
+               pwm_plat_data->pwm_init_vol = be32_to_cpu(*init_vol);\r
+       \r
+       max_vol = of_get_property(np, "rockchip,pwm_max_voltage", NULL);\r
+       if (max_vol)\r
+               pwm_plat_data->pwm_max_vol = be32_to_cpu(*max_vol);\r
+       \r
+       min_vol = of_get_property(np, "rockchip,pwm_min_voltage", NULL);\r
+       if (min_vol)\r
+               pwm_plat_data->pwm_min_vol = be32_to_cpu(*min_vol);\r
+       \r
+       suspend_vol = of_get_property(np, "rockchip,pwm_suspend_voltage", NULL);\r
+       if (suspend_vol)\r
+               pwm_plat_data->pwm_suspend_vol = be32_to_cpu(*suspend_vol);\r
 \r
-       snprintf(dcdc->name, sizeof(dcdc->name), "PWM_DCDC%d", id + 1);\r
-       dcdc->desc.name = dcdc->name;\r
-       dcdc->desc.id = id;\r
-       dcdc->desc.type = REGULATOR_VOLTAGE;\r
-       dcdc->desc.n_voltages = ARRAY_SIZE(pwm_voltage_map);\r
-       dcdc->desc.ops = &pwm_voltage_ops;\r
-       dcdc->desc.owner = THIS_MODULE;\r
-       dcdc->pdata = pdata;\r
-       printk("%s:n_voltages=%d\n",__func__,dcdc->desc.n_voltages);\r
-       dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,\r
-                                            pdata->init_data, dcdc);\r
-       if (IS_ERR(dcdc->regulator)) {\r
-               ret = PTR_ERR(dcdc->regulator);\r
-               dev_err(&pdev->dev, "Failed to register PWM_DCDC%d: %d\n",\r
-                       id + 1, ret);\r
-               goto err;\r
+       coefficient  = of_get_property(np, "rockchip,pwm_coefficient", NULL);\r
+       if (coefficient )\r
+               pwm_plat_data->pwm_coefficient = be32_to_cpu(*coefficient );\r
+       \r
+       id  = of_get_property(np, "rockchip,pwm_id", NULL);\r
+       if (id )\r
+               pwm_plat_data->pwm_id = be32_to_cpu(*id );\r
+\r
+       prop = of_find_property(np, "rockchip,pwm_voltage_map", &length);\r
+       if (!prop)
+               return NULL;\r
+       pwm_plat_data->pwm_vol_map_count = length / sizeof(u32);\r
+       if (pwm_plat_data->pwm_vol_map_count > 0) {\r
+               size_t size = sizeof(*pwm_plat_data->pwm_voltage_map) * pwm_plat_data->pwm_vol_map_count;\r
+
+       pwm_plat_data->pwm_voltage_map = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);\r
+       if (! pwm_plat_data->pwm_voltage_map)\r
+               return NULL;\r
+       ret = of_property_read_u32_array(np, "rockchip,pwm_voltage_map",pwm_plat_data->pwm_voltage_map, pwm_plat_data->pwm_vol_map_count);\r
+       if (ret < 0)\r
+               printk("pwm voltage map not specified\n");\r
        }\r
+       return pwm_plat_data;\r
+}
+#else
+static inline struct pwm_regulator_board *pwm_regulator_parse_dt(\r
+                       struct platform_device *pdev,
+                       struct of_regulator_match **pwm_reg_matches)\r
+{
+       return NULL;\r
+}
+#endif\r
 \r
-       snprintf(gpio_name, sizeof(gpio_name), "PWM_DCDC%d", id + 1);\r
-       ret = gpio_request(pdata->pwm_gpio,gpio_name);\r
-       if (ret) {\r
-               dev_err(&pdev->dev,"failed to request pwm gpio\n");\r
-               goto err_gpio;\r
-       }\r
 \r
-       dcdc->pwm_clk = rk_pwm_get_clk(pwm_id);\r
-       dcdc->pwm_base = rk_pwm_get_base(pwm_id);\r
-       if (IS_ERR(dcdc->pwm_clk)) {\r
-               printk("pwm_clk get error %p\n", dcdc->pwm_clk);\r
-               return -EINVAL;\r
+static int __init pwm_regulator_probe(struct platform_device *pdev)\r
+{\r
+       struct pwm_platform_data *pdata = pdev->dev.platform_data;\r
+       struct pwm_regulator_board *pwm_pdev;\r
+       struct of_regulator_match *pwm_reg_matches = NULL;\r
+       struct regulator_init_data *reg_data;\r
+       struct regulator_config config = { };\r
+       const char *rail_name = NULL;\r
+       struct regulator_dev *pwm_rdev;\r
+       int ret,i=0;\r
+       struct regulator *dc;\r
+\r
+       pwm_pdev = devm_kzalloc(&pdev->dev, sizeof(*pwm_pdev),\r
+                                       GFP_KERNEL);\r
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata),\r
+                                       GFP_KERNEL);\r
+       \r
+       if (pdev->dev.of_node)\r
+               pwm_pdev = pwm_regulator_parse_dt(pdev,&pwm_reg_matches);\r
+\r
+       if (!pwm_pdev) {\r
+               dev_err(&pdev->dev, "Platform data not found\n");
+               return -EINVAL;
        }\r
-       clk_enable(dcdc->pwm_clk);\r
+       \r
+       if (!pwm_pdev->pwm_init_vol)\r
+               pdata->pwm_voltage = 1100000;   // default 1.1v\r
+       else\r
+               pdata->pwm_voltage = pwm_pdev->pwm_init_vol;    \r
 \r
-       dcdc->suspend_lrc = 0x12;\r
-       switch (pdata->suspend_voltage)\r
-       {\r
-       case 1000000:\r
-       default:\r
-               dcdc->suspend_hrc = 0x10;\r
-               break;\r
-       case 1050000:\r
-               dcdc->suspend_hrc = 0x0e;\r
-               break;\r
-       case 1100000:\r
-               dcdc->suspend_hrc = 0x0c;\r
-               break;\r
-       case 1150000:\r
-               dcdc->suspend_hrc = 0x0a;\r
-               break;\r
+       if(!pwm_pdev->pwm_max_vol)\r
+               pdata->max_uV = 1400000;\r
+       else\r
+               pdata->max_uV = pwm_pdev->pwm_max_vol;\r
+\r
+       if(!pwm_pdev->pwm_min_vol)\r
+               pdata->min_uV = 1000000;\r
+       else\r
+               pdata->min_uV = pwm_pdev->pwm_min_vol;\r
+\r
+       if(pwm_pdev->pwm_suspend_vol < pwm_pdev->pwm_min_vol)\r
+               pdata->suspend_voltage = pwm_pdev->pwm_min_vol;\r
+       else if(pwm_pdev->pwm_suspend_vol > pwm_pdev->pwm_max_vol)\r
+               pdata->suspend_voltage = pwm_pdev->pwm_max_vol;\r
+       else\r
+               pdata->suspend_voltage = pwm_pdev->pwm_suspend_vol;\r
+       \r
+       pdata->pwm_voltage_map = pwm_pdev->pwm_voltage_map;\r
+       pdata->pwm_id = pwm_pdev->pwm_id;\r
+       pdata->coefficient = pwm_pdev->pwm_coefficient;\r
+       pdata->pwm_vol_map_count = pwm_pdev->pwm_vol_map_count;\r
+       \r
+       pdata->pwm = devm_pwm_get(&pdev->dev, NULL);\r
+       if (IS_ERR(pdata->pwm)) {\r
+               dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");
+
+               pdata->pwm = pwm_request(pdata->pwm_id, "pwm-regulator");\r
+               if (IS_ERR(pdata->pwm)) {\r
+                       dev_err(&pdev->dev, "unable to request legacy PWM\n");
+                       ret = PTR_ERR(pdata->pwm);\r
+                       goto err;\r
+               }
        }\r
+       pwm_enable(pdata->pwm);\r
+       if (pdata->pwm_period_ns > 0)\r
+               pwm_set_period(pdata->pwm, pdata->pwm_period_ns);\r
+
+       pdata->period = pwm_get_period(pdata->pwm);\r
 \r
-       g_dcdc  = dcdc;\r
-       platform_set_drvdata(pdev, dcdc);       \r
-       printk(KERN_INFO "pwm_regulator.%d: driver initialized\n",id);\r
-       pwm_regulator_set_voltage(dcdc->regulator,pdata->pwm_voltage,pdata->pwm_voltage,&selector);\r
+       g_pdata = pdata;\r
        \r
+       if (pwm_pdev){\r
+               pdata->num_regulators = pwm_pdev ->num_regulators;\r
+               pdata->rdev = kcalloc(pdata->num_regulators,sizeof(struct regulator_dev *), GFP_KERNEL);\r
+               if (!pdata->rdev) {\r
+                       return -ENOMEM;
+               }\r
+               /* Instantiate the regulators */\r
+               for (i = 0; i < pdata->num_regulators; i++) {\r
+               reg_data = pwm_pdev->pwm_init_data[i];\r
+               if (!reg_data)
+                       continue;
+               config.dev = &pdev->dev;\r
+               config.driver_data = pdata;\r
+               if (&pdev->dev.of_node)\r
+                       config.of_node = pwm_pdev->of_node[i];\r
+               if (reg_data && reg_data->constraints.name)
+                               rail_name = reg_data->constraints.name;
+                       else
+                               rail_name = regulators[i].name;
+                       reg_data->supply_regulator = rail_name;
+       
+               config.init_data =reg_data;
+\r
+               pwm_rdev = regulator_register(&regulators[i],&config);\r
+               if (IS_ERR(pwm_rdev)) {\r
+                       printk("failed to register %d regulator\n",i);
+               goto err;
+               }
+               pdata->rdev[i] = pwm_rdev;\r
+               }
+       }\r
+       /*********set pwm vol by defult***********/\r
+       //dc = regulator_get(NULL,"vdd_gpu");\r
+       //regulator_set_voltage(dc,pdata->pwm_voltage,pdata->pwm_voltage);\r
+       /**************************************/\r
        return 0;\r
-\r
-\r
-err_gpio:\r
-       gpio_free(pdata->pwm_gpio);\r
 err:\r
        printk("%s:error\n",__func__);\r
        return ret;\r
@@ -311,42 +384,32 @@ err:
 \r
 void pwm_suspend_voltage(void)\r
 {\r
-       struct rk_pwm_dcdc *dcdc = g_dcdc;\r
-       \r
-       if(!dcdc)\r
-               return;\r
        \r
-       dcdc->backup_hrc = readl_relaxed(dcdc->pwm_base + PWM_REG_HRC);\r
-       dcdc->backup_lrc = readl_relaxed(dcdc->pwm_base + PWM_REG_LRC);\r
-\r
-       __rk_pwm_setup(dcdc->pwm_base, PWM_DIV, dcdc->suspend_hrc, dcdc->suspend_lrc);\r
 }\r
 \r
 void pwm_resume_voltage(void)\r
 {\r
-       struct rk_pwm_dcdc *dcdc = g_dcdc;      \r
-       \r
-       if(!dcdc)\r
-               return;\r
-       __rk_pwm_setup(dcdc->pwm_base, PWM_DIV, dcdc->backup_hrc, dcdc->backup_lrc);\r
+\r
 }\r
 \r
-static int __devexit pwm_regulator_remove(struct platform_device *pdev)\r
+static int pwm_regulator_remove(struct platform_device *pdev)\r
 {\r
        struct pwm_platform_data *pdata = pdev->dev.platform_data;\r
-       struct regulator_dev *rdev = platform_get_drvdata(pdev);\r
-\r
-       regulator_unregister(rdev);\r
-       gpio_free(pdata->pwm_gpio);\r
+       int i;\r
 \r
+       for (i = 0; i < pdata->num_regulators; i++)\r
+               if (pdata->rdev[i])\r
+                       regulator_unregister(pdata->rdev[i]);\r
+       kfree(pdata->rdev);\r
        return 0;\r
 }\r
 \r
 static struct platform_driver pwm_regulator_driver = {\r
        .driver = {\r
                .name = "pwm-voltage-regulator",\r
+               .of_match_table =of_match_ptr(pwm_of_match),\r
        },\r
-       .remove = __devexit_p(pwm_regulator_remove),\r
+       .remove = pwm_regulator_remove,\r
 };\r
 \r
 \r
@@ -360,6 +423,7 @@ static void __exit pwm_regulator_module_exit(void)
        platform_driver_unregister(&pwm_regulator_driver);\r
 }\r
 \r
-fs_initcall(pwm_regulator_module_init);\r
+//fs_initcall(pwm_regulator_module_init);\r
+module_init(pwm_regulator_module_init);\r
 module_exit(pwm_regulator_module_exit);\r
 MODULE_LICENSE("GPL");\r
index 8baeb93624466e9edca7a5cb5a6e90b503d5771d..973be235a24b399cee987cae6e8854621a51d22b 100755 (executable)
@@ -17,7 +17,7 @@
 #define __LINUX_REGULATOR_PWM_H\r
 \r
 #include <linux/regulator/machine.h>\r
-#include <plat/pwm.h>\r
+//#include <plat/pwm.h>\r
 \r
 #define PWM_DIV              PWM_DIV2\r
 \r
@@ -27,17 +27,37 @@ struct regulator_init_data;
 struct pwm_platform_data {\r
        int     pwm_id;\r
        int     pwm_gpio;\r
-       //char  pwm_iomux_name[50];\r
-       char*   pwm_iomux_name;\r
-       unsigned int    pwm_iomux_pwm;\r
-       int     pwm_iomux_gpio;\r
-       int     pwm_voltage;\r
-       int     suspend_voltage;\r
-       int     coefficient;\r
-       int     min_uV;\r
-       int     max_uV;\r
-       const int       *pwm_voltage_map;\r
+       struct pwm_device       *pwm;\r
+       unsigned int            period;\r
+       unsigned int pwm_period_ns;\r
+       unsigned int            scale;\r
+       unsigned int    pwm_voltage;\r
+       unsigned int    suspend_voltage;\r
+       unsigned int    coefficient;\r
+       unsigned int    min_uV;\r
+       unsigned int    max_uV;\r
+       unsigned int    *pwm_voltage_map;\r
        struct regulator_init_data *init_data;\r
+       int num_regulators;\r
+       struct regulator_dev **rdev;\r
+       int pwm_vol_map_count;\r
+};\r
+\r
+struct pwm_regulator_board {\r
+       int pwm_gpio;\r
+       struct pwm_device       *pwm;\r
+       struct regulator_init_data *pwm_init_data[4];\r
+       struct device_node *of_node[4];\r
+       int     pwm_id;\r
+       unsigned int *pwm_voltage_map; \r
+       unsigned int pwm_init_vol;\r
+       unsigned int pwm_max_vol;\r
+       unsigned int pwm_min_vol;\r
+       unsigned int pwm_suspend_vol;\r
+       unsigned int pwm_coefficient;\r
+       int num_regulators;\r
+       struct regulator_dev **rdev;\r
+       int pwm_vol_map_count;\r
 };\r
 \r
 #endif\r