1 /* drivers/regulator/rk29-pwm-regulator.c
\r
3 * Copyright (C) 2010 ROCKCHIP, Inc.
\r
5 * This software is licensed under the terms of the GNU General Public
\r
6 * License version 2, as published by the Free Software Foundation, and
\r
7 * may be copied, distributed, and modified under those terms.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
15 /*******************************************************************/
\r
16 /* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED. */
\r
17 /*******************************************************************
\r
18 FILE : rk29-pwm-regulator.c
\r
19 DESC : rk29 pwm regulator driver
\r
25 ********************************************************************/
\r
28 #include <linux/bug.h>
\r
29 #include <linux/err.h>
\r
30 #include <linux/platform_device.h>
\r
31 #include <linux/kernel.h>
\r
32 #include <linux/clk.h>
\r
34 #include <linux/delay.h>
\r
35 #include <linux/regulator/driver.h>
\r
36 #include <linux/regulator/rk29-pwm-regulator.h>
\r
37 #include <mach/iomux.h>
\r
38 #include <linux/gpio.h>
\r
42 #define DBG(x...) printk(KERN_INFO x)
\r
48 #define PWM_VCORE_120 40
\r
49 #define PWM_VCORE_125 32
\r
50 #define PWM_VCORE_130 21
\r
51 #define PWM_VCORE_135 10
\r
52 #define PWM_VCORE_140 0
\r
55 #define pwm_write_reg(id, addr, val) __raw_writel(val, addr+(RK29_PWM_BASE+id*0x10))
\r
56 #define pwm_read_reg(id, addr) __raw_readl(addr+(RK29_PWM_BASE+id*0x10))
\r
59 const static int pwm_voltage_map[] = {
\r
60 950, 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350, 1375, 1400
\r
63 static struct clk *pwm_clk;
\r
65 static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)
\r
68 int id = pdata->pwm_id;
\r
69 unsigned long clkrate;
\r
71 clkrate = clk_get_rate(pwm_clk);
\r
73 if ( id >3 || id <0 )
\r
78 // iomux pwm2 to gpio2_a[3]
\r
79 rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_gpio);
\r
80 // set gpio to low level
\r
81 gpio_set_value(pdata->pwm_gpio,GPIO_LOW);
\r
83 else if (rate <= 100)
\r
86 rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_pwm);
\r
88 pwm_write_reg(id,PWM_REG_CTRL, PWM_DIV|PWM_RESET);
\r
89 divh = clkrate / nHz;
\r
90 divh = divh >> (1+(PWM_DIV>>9));
\r
91 pwm_write_reg(id,PWM_REG_LRC,(divh == 0)?1:divh);
\r
93 divTotal =pwm_read_reg(id,PWM_REG_LRC);
\r
94 divh = divTotal*rate/100;
\r
95 pwm_write_reg(id, PWM_REG_HRC, divh?divh:1);
\r
96 pwm_write_reg(id,PWM_REG_CNTR,0);
\r
97 pwm_write_reg(id, PWM_REG_CTRL,pwm_read_reg(id,PWM_REG_CTRL)|PWM_DIV|PWM_ENABLE|PWM_TimeEN);
\r
104 usleep_range(10*1000, 10*1000);
\r
110 static int pwm_regulator_list_voltage(struct regulator_dev *dev,unsigned int index)
\r
112 DBG("Enter %s, index =%d\n",__FUNCTION__,index);
\r
113 if (index < sizeof(pwm_voltage_map)/sizeof(int))
\r
114 return pwm_voltage_map[index];
\r
119 static int pwm_regulator_is_enabled(struct regulator_dev *dev)
\r
121 DBG("Enter %s\n",__FUNCTION__);
\r
125 static int pwm_regulator_enable(struct regulator_dev *dev)
\r
127 DBG("Enter %s\n",__FUNCTION__);
\r
131 static int pwm_regulator_disable(struct regulator_dev *dev)
\r
133 DBG("Enter %s\n",__FUNCTION__);
\r
137 static int pwm_regulator_get_voltage(struct regulator_dev *dev)
\r
139 struct pwm_platform_data *pdata = rdev_get_drvdata(dev);
\r
141 DBG("Enter %s\n",__FUNCTION__);
\r
143 return (pdata->pwm_voltage*1000);
\r
146 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
\r
147 static int pwm_regulator_set_voltage(struct regulator_dev *dev,
\r
148 int min_uV, int max_uV, unsigned *selector)
\r
150 static int pwm_regulator_set_voltage(struct regulator_dev *dev,
\r
151 int min_uV, int max_uV)
\r
154 struct pwm_platform_data *pdata = rdev_get_drvdata(dev);
\r
156 const int *voltage_map = pwm_voltage_map;
\r
158 int min_mV = min_uV /1000, max_mA = max_uV / 1000;
\r
160 u32 size = sizeof(pwm_voltage_map)/sizeof(int), i, vol,pwm_value;
\r
162 DBG("%s: min_uV = %d, max_uV = %d\n",__FUNCTION__, min_uV,max_uV);
\r
164 if (min_mV < voltage_map[0] ||max_mA > voltage_map[size-1])
\r
167 for (i = 0; i < size; i++)
\r
169 if (voltage_map[i] >= min_mV)
\r
174 vol = voltage_map[i];
\r
176 pdata->pwm_voltage = vol;
\r
178 // VDD12 = 1.4 - 0.476*D , ÆäÖÐDΪPWMÕ¼¿Õ±È,
\r
179 pwm_value = 100*(1400-vol)/476; // pwm_value %
\r
182 if (pwm_set_rate(pdata,1000*1000,pwm_value)!=0)
\r
185 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
\r
193 static struct regulator_ops pwm_voltage_ops = {
\r
194 .list_voltage = pwm_regulator_list_voltage,
\r
195 .set_voltage =pwm_regulator_set_voltage,
\r
196 .get_voltage = pwm_regulator_get_voltage,
\r
197 .enable = pwm_regulator_enable,
\r
198 .disable = pwm_regulator_disable,
\r
199 .is_enabled = pwm_regulator_is_enabled,
\r
202 static struct regulator_desc pwm_regulator= {
\r
203 .name = "pwm-regulator",
\r
204 .ops = &pwm_voltage_ops,
\r
205 .type = REGULATOR_VOLTAGE,
\r
208 static int __devinit pwm_regulator_probe(struct platform_device *pdev)
\r
211 struct pwm_platform_data *pdata = pdev->dev.platform_data;
\r
212 struct regulator_dev *rdev;
\r
218 if (!pdata->pwm_voltage)
\r
219 pdata->pwm_voltage = 1200; // default 1.2v
\r
221 rdev = regulator_register(&pwm_regulator, &pdev->dev,
\r
222 pdata->init_data, pdata);
\r
223 if (IS_ERR(rdev)) {
\r
224 dev_dbg(&pdev->dev, "couldn't register regulator\n");
\r
225 return PTR_ERR(rdev);
\r
228 ret = gpio_request(pdata->pwm_gpio,"pwm");
\r
231 dev_err(&pdev->dev,"failed to request pwm gpio\n");
\r
235 pwm_clk = clk_get(NULL, "pwm");
\r
236 clk_enable(pwm_clk);
\r
239 platform_set_drvdata(pdev, rdev);
\r
240 printk(KERN_INFO "pwm_regulator: driver initialized\n");
\r
246 gpio_free(pdata->pwm_gpio);
\r
252 static int __devexit pwm_regulator_remove(struct platform_device *pdev)
\r
254 struct pwm_platform_data *pdata = pdev->dev.platform_data;
\r
255 struct regulator_dev *rdev = platform_get_drvdata(pdev);
\r
257 regulator_unregister(rdev);
\r
258 gpio_free(pdata->pwm_gpio);
\r
263 static struct platform_driver pwm_regulator_driver = {
\r
265 .name = "pwm-voltage-regulator",
\r
267 .remove = __devexit_p(pwm_regulator_remove),
\r
271 static int __init pwm_regulator_module_init(void)
\r
273 return platform_driver_probe(&pwm_regulator_driver, pwm_regulator_probe);
\r
276 static void __exit pwm_regulator_module_exit(void)
\r
278 platform_driver_unregister(&pwm_regulator_driver);
\r
282 subsys_initcall(pwm_regulator_module_init);
\r
284 module_exit(pwm_regulator_module_exit);
\r
286 MODULE_LICENSE("GPL");
\r
287 MODULE_AUTHOR("hxy <hxy@rock-chips.com>");
\r
288 MODULE_DESCRIPTION("k29 pwm change driver");
\r