rk2928:sdk:support pwm set voltage
author张晴 <zhangqing@rock-chips.com>
Wed, 15 Aug 2012 09:20:59 +0000 (17:20 +0800)
committer张晴 <zhangqing@rock-chips.com>
Wed, 15 Aug 2012 09:20:59 +0000 (17:20 +0800)
arch/arm/mach-rk2928/board-rk2928-sdk-tps65910.c
arch/arm/mach-rk2928/board-rk2928-sdk.c
drivers/regulator/rk30-pwm-regulator.c
include/linux/regulator/rk29-pwm-regulator.h [changed mode: 0644->0755]

index 51cf60dc20292d41bdbef6cf4bb8916098b3ccfe..4b8d6058d3eed5061580a4c3bc28ccb1e36fb0b2 100755 (executable)
@@ -237,6 +237,10 @@ int tps65910_post_init(struct tps65910 *tps65910)
        struct regulator *dcdc;
        struct regulator *ldo;
        printk("%s,line=%d\n", __func__,__LINE__);
+
+       #ifdef CONFIG_RK30_PWM_REGULATOR
+       platform_device_register(&pwm_regulator_device[0]);
+       #endif
        
        dcdc = regulator_get(NULL, "vio");      //vcc_io
        regulator_set_voltage(dcdc, 3300000, 3300000);
@@ -315,15 +319,6 @@ int tps65910_post_init(struct tps65910 *tps65910)
        regulator_put(ldo);
        udelay(100);
 
-       #ifdef CONFIG_RK30_PWM_REGULATOR
-       dcdc = regulator_get(NULL, "vdd_core"); // vdd_log
-       regulator_set_voltage(dcdc, 1100000, 1100000);
-       regulator_enable(dcdc);
-       printk("%s set vdd_core=%dmV end\n", __func__, regulator_get_voltage(dcdc));
-       regulator_put(dcdc);
-       udelay(100);
-       #endif
-
        printk("%s,line=%d END\n", __func__,__LINE__);
        
        return 0;
index fb48103c02459db78845286584486cd13d96e6a4..57eef7b606dec0ca6e1e934ce9633f4ba0c713a4 100755 (executable)
@@ -379,6 +379,59 @@ static struct platform_device device_ion = {
 };
 #endif
 
+#if CONFIG_RK30_PWM_REGULATOR
+const static int pwm_voltage_map[] = {
+       1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000
+};
+
+static struct regulator_consumer_supply pwm_dcdc1_consumers[] = {
+       {
+               .supply = "vdd_core",
+       }
+};
+
+struct regulator_init_data pwm_regulator_init_dcdc[1] =
+{
+       {
+               .constraints = {
+                       .name = "PWM_DCDC1",
+                       .min_uV = 600000,
+                       .max_uV = 1800000,      //0.6-1.8V
+                       .apply_uV = true,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+               },
+               .num_consumer_supplies = ARRAY_SIZE(pwm_dcdc1_consumers),
+               .consumer_supplies = pwm_dcdc1_consumers,
+       },
+};
+
+static struct pwm_platform_data pwm_regulator_info[1] = {
+       {
+               .pwm_id = 2,
+               .pwm_gpio = RK2928_PIN0_PD4,
+               .pwm_iomux_name = GPIO0D4_PWM_2_NAME,
+               .pwm_iomux_pwm = GPIO0D_PWM_2, 
+               .pwm_iomux_gpio = GPIO0D_GPIO0D4,
+               .pwm_voltage = 1200000,
+               .suspend_voltage = 1050000,
+               .min_uV = 1000000,
+               .max_uV = 1400000,
+               .coefficient = 455,     //45.5%
+               .pwm_voltage_map = pwm_voltage_map,
+               .init_data      = &pwm_regulator_init_dcdc[0],
+       },
+};
+
+struct platform_device pwm_regulator_device[1] = {
+       {
+               .name = "pwm-voltage-regulator",
+               .id = 0,
+               .dev            = {
+                       .platform_data = &pwm_regulator_info[0],
+               }
+       },
+};
+#endif
 /**************************************************************************************************
  * SDMMC devices,  include the module of SD,MMC,and sdio.noted by xbw at 2012-03-05
 **************************************************************************************************/
@@ -717,10 +770,15 @@ static void __init rk30_i2c_register_board_info(void)
 //end of i2c
 
 #define POWER_ON_PIN RK2928_PIN3_PC5   //power_hold
-static void rk30_pm_power_off(void)
+static void rk2928_pm_power_off(void)
 {
-       printk(KERN_ERR "rk30_pm_power_off start...\n");
+       printk(KERN_ERR "rk2928_pm_power_off start...\n");
+       
+       #if defined(CONFIG_MFD_TPS65910)
+               tps65910_device_shutdown();//tps65910 shutdown
+       #endif
        gpio_direction_output(POWER_ON_PIN, GPIO_LOW);
+       
 };
 
 static void __init rk2928_board_init(void)
@@ -729,7 +787,7 @@ static void __init rk2928_board_init(void)
        gpio_direction_output(POWER_ON_PIN, GPIO_HIGH);
         gpio_free(POWER_ON_PIN);
        
-       pm_power_off = rk30_pm_power_off;
+       pm_power_off = rk2928_pm_power_off;
        
        rk30_i2c_register_board_info();
        spi_register_board_info(board_spi_devices, ARRAY_SIZE(board_spi_devices));
index 7a89527b0b06719dd30bf1fa5591f122501b4a14..ce7aee35eee5ccae3e2f11b5a2e7e956d24dd35d 100755 (executable)
@@ -66,34 +66,37 @@ struct rk_pwm_dcdc {
 #define pwm_read_reg(id, addr)              __raw_readl(addr+(RK30_PWM01_BASE+(id>>1)*0x20000+id*0x10))\r
 #elif defined(CONFIG_ARCH_RK29)\r
 #define pwm_write_reg(id, addr, val)        __raw_writel(val, addr+(RK29_PWM_BASE+id*0x10))\r
-#define pwm_read_reg(id, addr)              __raw_readl(addr+(RK29_PWM_BASE+id*0x10))    \r
+#define pwm_read_reg(id, addr)              __raw_readl(addr+(RK29_PWM_BASE+id*0x10))   \r
+#elif defined(CONFIG_ARCH_RK2928)\r
+#define pwm_write_reg(id, addr, val)        __raw_writel(val, addr+(RK2928_PWM_BASE+id*0x10))\r
+#define pwm_read_reg(id, addr)              __raw_readl(addr+(RK2928_PWM_BASE+id*0x10))\r
 #endif\r
 \r
 const static int pwm_voltage_map[] = {\r
-       850000,875000,900000,925000,950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000\r
+       1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000\r
 };\r
 \r
 static struct clk *pwm_clk[2];\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 divh,divTotal;\r
        int id = pdata->pwm_id;\r
        unsigned long clkrate;\r
-       \r
-       if ( id >3 || id <0 )\r
+       /*\r
+       if ( id >2 || id <0 )\r
        {\r
                printk("%s:pwm id error,id=%d\n",__func__,id);\r
                return -1;\r
        }\r
 \r
        if((id==0) || (id == 1))\r
+       */\r
        clkrate = clk_get_rate(pwm_clk[0]);\r
-       else    \r
-       clkrate = clk_get_rate(pwm_clk[1]);\r
        \r
-       DBG("%s:id=%d,rate=%d,clkrate=%d\n",__func__,id,rate,clkrate);\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
@@ -101,9 +104,9 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)
                //disable pull up or down\r
                gpio_pull_updown(pdata->pwm_gpio,PullDisable);\r
                // set gpio to low level\r
-               gpio_set_value(pdata->pwm_gpio,GPIO_LOW);\r
+               gpio_direction_output(pdata->pwm_gpio,GPIO_LOW);\r
        }\r
-       else if (rate <= 100)\r
+       else if (rate < 100)\r
        {\r
                // iomux pwm\r
                rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_pwm);\r
@@ -119,6 +122,16 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)
                pwm_write_reg(id,PWM_REG_CNTR,0);\r
                pwm_write_reg(id, PWM_REG_CTRL,pwm_read_reg(id,PWM_REG_CTRL)|PWM_DIV|PWM_ENABLE|PWM_TimeEN);\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
+\r
+       }\r
        else\r
        {\r
                printk("%s:rate error\n",__func__);\r
@@ -132,8 +145,9 @@ 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
-       if (index < sizeof(pwm_voltage_map)/sizeof(int))\r
-               return pwm_voltage_map[index];\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
        else\r
                return -1;\r
 }\r
@@ -176,15 +190,14 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev,
 #endif\r
 {         \r
        struct rk_pwm_dcdc *dcdc = rdev_get_drvdata(dev);\r
-       const int *voltage_map = pwm_voltage_map;\r
-\r
-       int min_mV = min_uV, max_mA = max_uV;\r
-\r
-       u32 size = sizeof(pwm_voltage_map)/sizeof(int), i, vol,pwm_value;\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
 \r
        DBG("%s:  min_uV = %d, max_uV = %d\n",__FUNCTION__, min_uV,max_uV);\r
 \r
-       if (min_mV < voltage_map[0] ||max_mA > voltage_map[size-1])\r
+       if (min_uV < voltage_map[0] ||max_uV > voltage_map[size-1])\r
        {\r
                printk("%s:voltage is out of table\n",__func__);\r
                return -EINVAL;\r
@@ -192,7 +205,7 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev,
 \r
        for (i = 0; i < size; i++)\r
        {\r
-               if (voltage_map[i] >= min_mV)\r
+               if (voltage_map[i] >= min_uV)\r
                        break;\r
        }\r
 \r
@@ -201,9 +214,8 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev,
 \r
        dcdc->pdata->pwm_voltage = vol;\r
 \r
-       // VDD12 = 1.42 - 0.56*D , ÆäÖÐDΪPWMÕ¼¿Õ±È, \r
-       pwm_value = (1325000-vol)/5800;  // pwm_value %\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
        {\r
@@ -242,7 +254,6 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev)
        struct pwm_platform_data *pdata = pdev->dev.platform_data;\r
        struct rk_pwm_dcdc *dcdc;\r
        int pwm_id  =  pdata->pwm_id;\r
-       struct regulator_dev *rdev;\r
        int id = pdev->id;\r
        int ret ;\r
     char gpio_name[20];\r
@@ -251,8 +262,23 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev)
                return -ENODEV;\r
 \r
        if (!pdata->pwm_voltage)\r
-               pdata->pwm_voltage = 1200000;   // default 1.2v\r
+               pdata->pwm_voltage = 1100000;   // default 1.1v\r
 \r
+       if(!pdata->pwm_voltage_map)\r
+               pdata->pwm_voltage_map = pwm_voltage_map;\r
+\r
+       if(!pdata->max_uV)\r
+               pdata->max_uV = 1400000;\r
+\r
+       if(!pdata->min_uV)\r
+               pdata->min_uV = 1000000;\r
+       \r
+       if(pdata->suspend_voltage < pdata->min_uV)\r
+               pdata->suspend_voltage = pdata->min_uV;\r
+       \r
+       if(pdata->suspend_voltage > pdata->max_uV)      \r
+               pdata->suspend_voltage = pdata->max_uV;\r
+       \r
        dcdc = kzalloc(sizeof(struct rk_pwm_dcdc), GFP_KERNEL);\r
        if (dcdc == NULL) {
                dev_err(&pdev->dev, "Unable to allocate private data\n");
@@ -263,11 +289,11 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev)
        dcdc->desc.name = dcdc->name;
        dcdc->desc.id = id;
        dcdc->desc.type = REGULATOR_VOLTAGE;
-       dcdc->desc.n_voltages = 50;\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
-\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)) {
@@ -297,10 +323,17 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev)
                        pwm_clk[1] = clk_get(NULL, "pwm23");            \r
                        clk_enable(pwm_clk[1]);\r
                }\r
+#elif defined(CONFIG_ARCH_RK2928)\r
+               pwm_clk[0] = clk_get(NULL, "pwm01");\r
+               if (IS_ERR(pwm_clk[0])) {\r
+                       printk("pwm_clk get error %p\n", pwm_clk[0]);   \r
+                       return -EINVAL;\r
+               }\r
+               clk_enable(pwm_clk[0]);\r
 #endif\r
-\r
-\r
-       platform_set_drvdata(pdev, dcdc);\r
+       \r
+       g_dcdc  = dcdc;\r
+       platform_set_drvdata(pdev, dcdc);       \r
        printk(KERN_INFO "pwm_regulator.%d: driver initialized\n",id);\r
 \r
        return 0;\r
@@ -314,10 +347,73 @@ err:
 \r
 }\r
 \r
+static int  __sramdata g_PWM_REG_LRC = 0;\r
+static int  __sramdata g_PWM_REG_HRC = 0;\r
+void pwm_suspend_voltage(void)\r
+{\r
+       struct rk_pwm_dcdc *dcdc = g_dcdc;\r
+       int suspend_voltage = 0;\r
+       int pwm_id = 0;\r
+       \r
+       if(!dcdc)\r
+               return;\r
+       pwm_id = dcdc->pdata->pwm_id;\r
+       suspend_voltage = dcdc->pdata->suspend_voltage;\r
+       \r
+       g_PWM_REG_LRC = pwm_read_reg(pwm_id, PWM_REG_LRC);\r
+       g_PWM_REG_HRC = pwm_read_reg(pwm_id,PWM_REG_HRC);\r
+\r
+       switch(suspend_voltage)\r
+       {\r
+               case 1000000:\r
+               pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);\r
+               pwm_write_reg(pwm_id,PWM_REG_HRC,0x20); // 1 .00\r
+               break;\r
+               \r
+               case 1050000:\r
+               pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);\r
+               pwm_write_reg(pwm_id,PWM_REG_HRC,0x1c); // 1 .05\r
+               break;\r
+               \r
+               case 1100000:\r
+               pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);\r
+               pwm_write_reg(pwm_id,PWM_REG_HRC,0x18); // 1 .1\r
+               break;\r
+\r
+               case 1150000:\r
+               pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);\r
+               pwm_write_reg(pwm_id,PWM_REG_HRC,0x13); // 1 .15\r
+               break;\r
+\r
+               default:\r
+               pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);\r
+               pwm_write_reg(pwm_id,PWM_REG_HRC,0x20); // 1 .00\r
+               break;\r
+\r
+       }\r
+               \r
+}\r
+\r
+void pwm_resume_voltage(void)\r
+       {\r
+       struct rk_pwm_dcdc *dcdc = g_dcdc;      \r
+       int pwm_id = 0;\r
+       \r
+       if(!dcdc)\r
+               return;\r
+       pwm_id = dcdc->pdata->pwm_id;\r
+       pwm_write_reg(pwm_id, PWM_REG_LRC, g_PWM_REG_LRC);\r
+       pwm_write_reg(pwm_id,PWM_REG_HRC, g_PWM_REG_HRC);\r
+                       \r
+}\r
+\r
+\r
 static int pwm_regulator_suspend(struct platform_device *pdev, pm_message_t state)\r
 {\r
        struct pwm_platform_data *pdata = pdev->dev.platform_data;\r
-       pwm_set_rate(pdata,1000*1000,0);//pwm clk will change to 24M after suspend\r
+       //struct rk_pwm_dcdc *dcdc = platform_get_drvdata(pdev);\r
+       //unsigned selector = 0;\r
+       //pwm_regulator_set_voltage(dcdc->regulator, 1100000, 1100000, &selector);\r
        DBG("%s,pwm_id=%d\n",__func__,pdata->pwm_id);\r
        return 0;\r
 }\r
@@ -325,6 +421,9 @@ static int pwm_regulator_suspend(struct platform_device *pdev, pm_message_t stat
 static int pwm_regulator_resume(struct platform_device *pdev)\r
 {\r
        struct pwm_platform_data *pdata = pdev->dev.platform_data;\r
+       //struct rk_pwm_dcdc *dcdc = platform_get_drvdata(pdev);\r
+       //unsigned selector = 0;\r
+       //pwm_regulator_set_voltage(dcdc->regulator, 1150000, 1150000, &selector);\r
        DBG("%s,pwm_id=%d\n",__func__,pdata->pwm_id);\r
        return 0;\r
 }\r
@@ -361,7 +460,7 @@ static void __exit pwm_regulator_module_exit(void)
 }\r
 \r
 \r
-subsys_initcall(pwm_regulator_module_init);\r
+fs_initcall(pwm_regulator_module_init);\r
 \r
 module_exit(pwm_regulator_module_exit);\r
 \r
old mode 100644 (file)
new mode 100755 (executable)
index e0a0487..e74b812
@@ -57,6 +57,11 @@ struct pwm_platform_data {
        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
+       int     *pwm_voltage_map;\r
        struct regulator_init_data *init_data;\r
 };