-/* drivers/regulator/rk29-pwm-regulator.c\r
+/*\r
*\r
- * Copyright (C) 2010 ROCKCHIP, Inc.\r
+ * Copyright (C) 2013 ROCKCHIP, Inc.\r
*\r
* This software is licensed under the terms of the GNU General Public\r
* License version 2, as published by the Free Software Foundation, and\r
* GNU General Public License for more details.\r
*\r
*/\r
-/*******************************************************************/\r
-/* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED. */\r
-/*******************************************************************\r
-FILE : rk29-pwm-regulator.c\r
-DESC : rk29 pwm regulator driver\r
-AUTHOR : hxy\r
-DATE : 2010-12-20\r
-NOTES :\r
-$LOG: GPIO.C,V $\r
-REVISION 0.01\r
-********************************************************************/\r
#include <linux/bug.h>\r
#include <linux/err.h>\r
#include <linux/platform_device.h>\r
#include <mach/iomux.h>\r
#include <linux/gpio.h>\r
#include <mach/board.h>\r
-\r
+#include <plat/pwm.h>\r
\r
#if 0\r
#define DBG(x...) printk(KERN_INFO x)\r
#define DBG(x...)\r
#endif\r
\r
-\r
-#define PWM_VCORE_120 40\r
-#define PWM_VCORE_125 32\r
-#define PWM_VCORE_130 21\r
-#define PWM_VCORE_135 10\r
-#define PWM_VCORE_140 0\r
-\r
-#define PWM_DCDC_MAX_NAME 2\r
struct rk_pwm_dcdc {\r
- char name[PWM_DCDC_MAX_NAME];\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
-\r
-#if defined(CONFIG_ARCH_RK30)\r
-#define pwm_write_reg(id, addr, val) __raw_writel(val, addr+(RK30_PWM01_BASE+(id>>1)*0x20000)+id*0x10)\r
-#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
-#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
950000, 975000,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
+ u32 lrc, hrc;\r
int id = pdata->pwm_id;\r
unsigned long clkrate;\r
\r
-#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK2928)\r
- clkrate = clk_get_rate(pwm_clk[0]);\r
-#elif defined(CONFIG_ARCH_RK30)\r
- if (id == 0 || id == 1) {\r
- clkrate = clk_get_rate(pwm_clk[0]);\r
- } else if (id== 2 || id == 3) {\r
- clkrate = clk_get_rate(pwm_clk[1]);\r
- } else {\r
- printk("%s:pwm id error,id=%d\n",__func__,id);\r
- return -1;\r
- }\r
-#endif\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
}\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
\r
- pwm_write_reg(id,PWM_REG_CTRL, PWM_DIV|PWM_RESET);\r
- divh = clkrate / nHz;\r
- divh = divh >> (1+(PWM_DIV>>9));\r
- pwm_write_reg(id,PWM_REG_LRC,(divh == 0)?1:divh);\r
-\r
- divTotal =pwm_read_reg(id,PWM_REG_LRC);\r
- divh = divTotal*rate/100;\r
- pwm_write_reg(id, PWM_REG_HRC, divh?divh:1);\r
- 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
+ rk_pwm_setup(id, PWM_DIV, hrc, lrc);\r
}\r
else if (rate == 100)\r
{\r
return (dcdc->pdata->pwm_voltage);\r
}\r
\r
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))\r
static int pwm_regulator_set_voltage(struct regulator_dev *dev,\r
int min_uV, int max_uV, unsigned *selector)\r
-#else\r
-static int pwm_regulator_set_voltage(struct regulator_dev *dev,\r
- int min_uV, int max_uV)\r
-#endif\r
{ \r
struct rk_pwm_dcdc *dcdc = rdev_get_drvdata(dev);\r
const int *voltage_map = dcdc->pdata->pwm_voltage_map;\r
\r
}\r
\r
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))\r
*selector = i;\r
-#endif\r
\r
DBG("%s:ok,vol=%d,pwm_value=%d\n",__FUNCTION__,vol,pwm_value);\r
\r
.is_enabled = pwm_regulator_is_enabled,\r
};\r
\r
-static struct regulator_desc pwm_regulator= {\r
- .name = "pwm-regulator",\r
- .ops = &pwm_voltage_ops,\r
- .type = REGULATOR_VOLTAGE,\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
dev_err(&pdev->dev,"failed to request pwm gpio\n");\r
goto err_gpio;\r
}\r
- \r
-#if defined(CONFIG_ARCH_RK29)\r
- pwm_clk[0] = clk_get(NULL, "pwm");\r
-#elif defined(CONFIG_ARCH_RK30)\r
- if (pwm_id == 0 || pwm_id == 1)\r
- {\r
- pwm_clk[0] = clk_get(NULL, "pwm01"); \r
- clk_enable(pwm_clk[0]);\r
- }\r
- else if (pwm_id== 2 || pwm_id == 3)\r
- {\r
- 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
+ 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
+ }\r
+ clk_enable(dcdc->pwm_clk);\r
+\r
+ dcdc->suspend_lrc = 0x25;\r
+ switch (pdata->suspend_voltage)\r
+ {\r
+ case 1000000:\r
+ default:\r
+ dcdc->suspend_hrc = 0x20;\r
+ break;\r
+ case 1050000:\r
+ dcdc->suspend_hrc = 0x1c;\r
+ break;\r
+ case 1100000:\r
+ dcdc->suspend_hrc = 0x18;\r
+ break;\r
+ case 1150000:\r
+ dcdc->suspend_hrc = 0x13;\r
+ break;\r
+ }\r
+\r
g_dcdc = dcdc;\r
platform_set_drvdata(pdev, dcdc); \r
printk(KERN_INFO "pwm_regulator.%d: driver initialized\n",id);\r
\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
+ 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
- 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
+ __rk_pwm_setup(dcdc->pwm_base, PWM_DIV, dcdc->suspend_hrc, dcdc->suspend_lrc);\r
}\r
\r
void pwm_resume_voltage(void)\r
- {\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
- //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
-\r
-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
+ __rk_pwm_setup(dcdc->pwm_base, PWM_DIV, dcdc->backup_hrc, dcdc->backup_lrc);\r
}\r
\r
static int __devexit pwm_regulator_remove(struct platform_device *pdev)\r
.driver = {\r
.name = "pwm-voltage-regulator",\r
},\r
- .suspend = pwm_regulator_suspend,\r
- .resume = pwm_regulator_resume,\r
.remove = __devexit_p(pwm_regulator_remove),\r
};\r
\r
platform_driver_unregister(&pwm_regulator_driver);\r
}\r
\r
-\r
fs_initcall(pwm_regulator_module_init);\r
-\r
module_exit(pwm_regulator_module_exit);\r
-\r
MODULE_LICENSE("GPL");\r
-MODULE_AUTHOR("hxy <hxy@rock-chips.com>");\r
-MODULE_DESCRIPTION("k29 pwm change driver");\r