rk3288:pwm_regulator:slove pwm io set low when power on
[firefly-linux-kernel-4.4.55.git] / drivers / regulator / rockchip-pwm-regulator.c
1 /*\r
2  *\r
3  * Copyright (C) 2013 ROCKCHIP, Inc.\r
4  *\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
8  *\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
13  *\r
14  */\r
15 #include <linux/bug.h>\r
16 #include <linux/err.h>\r
17 #include <linux/platform_device.h>\r
18 #include <linux/kernel.h>\r
19 #include <linux/clk.h>\r
20 #include <asm/io.h>\r
21 #include <linux/delay.h>\r
22 #include <linux/slab.h>\r
23 #include <linux/regulator/rockchip-pwm-regulator.h>\r
24 #include <linux/gpio.h>\r
25 #include <linux/of_gpio.h>\r
26 #include <linux/module.h>\r
27 #include <linux/init.h>\r
28 #include <linux/err.h>\r
29 #include <linux/pwm.h>\r
30 \r
31 #include <linux/of.h>\r
32 #include <linux/of_device.h>\r
33 #include <linux/regulator/of_regulator.h>\r
34 #include <linux/regulator/driver.h>\r
35 #include <linux/regulator/machine.h>\r
36 \r
37 \r
38 #if 0\r
39 #define DBG(x...)       printk(KERN_INFO x)\r
40 #else\r
41 #define DBG(x...)\r
42 #endif\r
43 \r
44 const static int pwm_voltage_map[] = {\r
45         925000 ,950000, 975000,1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000,1375000,1400000\r
46 };\r
47         \r
48 static struct pwm_platform_data *g_pdata;\r
49 \r
50 static int pwm_set_rate(struct pwm_platform_data *pdata,u32 rate)\r
51 {\r
52         int duty_cycle;\r
53         DBG("%s:id=%d,rate=%d clkrate =%d\n",__func__,pdata->pwm_id,rate,pdata->period); \r
54 \r
55         duty_cycle = (rate * (pdata->period ) / 100) ;\r
56 \r
57         pwm_config(pdata->pwm, duty_cycle, pdata->period);\r
58 \r
59         pwm_enable(pdata->pwm);\r
60         \r
61         return (0);\r
62 }\r
63 \r
64 static int pwm_regulator_list_voltage(struct regulator_dev *dev,unsigned int index)\r
65 {\r
66         if (index <( g_pdata->pwm_vol_map_count +1))\r
67         return g_pdata->pwm_voltage_map[index];\r
68         else\r
69                 return -1;\r
70 }\r
71 \r
72 static int pwm_regulator_is_enabled(struct regulator_dev *dev)\r
73 {\r
74         DBG("Enter %s\n",__FUNCTION__);\r
75         return 0;\r
76 }\r
77 \r
78 static int pwm_regulator_enable(struct regulator_dev *dev)\r
79 {\r
80         DBG("Enter %s\n",__FUNCTION__);\r
81         return 0;\r
82 }\r
83 \r
84 static int pwm_regulator_disable(struct regulator_dev *dev)\r
85 {\r
86         DBG("Enter %s\n",__FUNCTION__);\r
87         return 0;\r
88 }\r
89 \r
90 static int pwm_regulator_get_voltage(struct regulator_dev *dev)\r
91 {       \r
92         u32 vol;\r
93 \r
94         DBG("Enter %s\n",__FUNCTION__);  \r
95 \r
96         vol = g_pdata->pwm_voltage;\r
97 \r
98         return vol;\r
99 }\r
100 \r
101 static int pwm_regulator_set_voltage(struct regulator_dev *dev,\r
102                 int min_uV, int max_uV, unsigned *selector)\r
103 {          \r
104         const int *voltage_map = g_pdata->pwm_voltage_map;\r
105         int max = g_pdata->max_uV;\r
106         int coefficient = g_pdata->coefficient;\r
107         u32 size = g_pdata->pwm_vol_map_count;\r
108         u32 i, vol,pwm_value;\r
109 \r
110         DBG("%s:  min_uV = %d, max_uV = %d\n",__FUNCTION__, min_uV,max_uV);\r
111 \r
112         if (min_uV < voltage_map[0] ||max_uV > voltage_map[size-1])\r
113         {\r
114                 printk("%s: voltage_map voltage is out of table\n",__func__);\r
115                 return -EINVAL;\r
116         }\r
117 \r
118         for (i = 0; i < size; i++)\r
119         {\r
120                 if (voltage_map[i] >= min_uV)\r
121                         break;\r
122         }\r
123         vol =  voltage_map[i];\r
124         g_pdata->pwm_voltage = vol;\r
125 \r
126         // VDD12 = 1.40 - 0.455*D , ÆäÖÐDΪPWMÕ¼¿Õ±È, \r
127         pwm_value = (max-vol)/coefficient/10;  // pwm_value %, coefficient *1000\r
128 \r
129         if (pwm_set_rate(g_pdata,pwm_value)!=0)\r
130         {\r
131                 printk("%s:fail to set pwm rate,pwm_value=%d\n",__func__,pwm_value);\r
132                 return -1;\r
133 \r
134         }\r
135         *selector = i;\r
136 \r
137         DBG("%s:ok,vol=%d,pwm_value=%d %d\n",__FUNCTION__,vol,pwm_value,g_pdata->pwm_voltage);\r
138 \r
139         return 0;\r
140 \r
141 }\r
142 \r
143 static struct regulator_ops pwm_voltage_ops = {\r
144         .list_voltage   = pwm_regulator_list_voltage,\r
145         .set_voltage    =pwm_regulator_set_voltage,\r
146         .get_voltage    = pwm_regulator_get_voltage,\r
147         .enable         = pwm_regulator_enable,\r
148         .disable        = pwm_regulator_disable,\r
149         .is_enabled     = pwm_regulator_is_enabled,\r
150 };\r
151 static struct regulator_desc regulators[] = {\r
152 \r
153         {\r
154                 .name = "PWM_DCDC1",\r
155                 .id = 0,\r
156                 .ops = &pwm_voltage_ops,\r
157                 .n_voltages =  ARRAY_SIZE(pwm_voltage_map),\r
158                 .type = REGULATOR_VOLTAGE,\r
159                 .owner = THIS_MODULE,\r
160         },\r
161 };\r
162 \r
163 #ifdef CONFIG_OF\r
164 static struct of_device_id pwm_of_match[] = {\r
165         { .compatible = "rockchip_pwm_regulator"},\r
166         { },\r
167 };\r
168 MODULE_DEVICE_TABLE(of, pwm_of_match);\r
169 \r
170 static struct of_regulator_match pwm_matches[] = {\r
171         { .name = "pwm_dcdc1",  .driver_data = (void *)0  },\r
172 };\r
173 \r
174 static struct pwm_regulator_board *pwm_regulator_parse_dt(\r
175                 struct platform_device *pdev,\r
176                 struct of_regulator_match **pwm_reg_matches)\r
177 {\r
178         struct pwm_regulator_board *pwm_plat_data;\r
179         struct device_node *np, *regulators;\r
180         struct of_regulator_match *matches;\r
181         int idx = 0, ret, count;\r
182         struct property *prop;\r
183         int length;\r
184         const __be32 *init_vol, *max_vol,*min_vol,*suspend_vol,*coefficient,*id;\r
185         \r
186          DBG("%s,line=%d\n", __func__,__LINE__);\r
187 \r
188         pwm_plat_data = devm_kzalloc(&pdev->dev, sizeof(*pwm_plat_data),\r
189                                         GFP_KERNEL);\r
190 \r
191         if (!pwm_plat_data) {\r
192                 dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n");\r
193                 return NULL;\r
194         }\r
195 \r
196         np = of_node_get(pdev->dev.of_node);\r
197         regulators = of_find_node_by_name(np, "regulators");\r
198         if (!regulators) {\r
199                 dev_err(&pdev->dev, "regulator node not found\n");\r
200                 return NULL;\r
201         }\r
202         count = ARRAY_SIZE(pwm_matches);\r
203         matches = pwm_matches;  \r
204         ret = of_regulator_match(&pdev->dev, regulators, matches, count);\r
205         of_node_put(regulators);\r
206         if (ret < 0) {\r
207                 dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",\r
208                         ret);\r
209                 return NULL;\r
210         }\r
211         \r
212         pwm_plat_data ->num_regulators = count;\r
213         *pwm_reg_matches = matches;\r
214         \r
215         for (idx = 0; idx < count; idx++) {\r
216                 if (!matches[idx].init_data || !matches[idx].of_node)\r
217                         continue;\r
218                 pwm_plat_data->pwm_init_data[idx] =matches[idx].init_data;\r
219                 pwm_plat_data->of_node[idx]=matches[idx].of_node;\r
220         }\r
221         \r
222         init_vol = of_get_property(np, "rockchip,pwm_voltage", NULL);\r
223         if (init_vol)\r
224                 pwm_plat_data->pwm_init_vol = be32_to_cpu(*init_vol);\r
225         \r
226         max_vol = of_get_property(np, "rockchip,pwm_max_voltage", NULL);\r
227         if (max_vol)\r
228                 pwm_plat_data->pwm_max_vol = be32_to_cpu(*max_vol);\r
229         \r
230         min_vol = of_get_property(np, "rockchip,pwm_min_voltage", NULL);\r
231         if (min_vol)\r
232                 pwm_plat_data->pwm_min_vol = be32_to_cpu(*min_vol);\r
233         \r
234         suspend_vol = of_get_property(np, "rockchip,pwm_suspend_voltage", NULL);\r
235         if (suspend_vol)\r
236                 pwm_plat_data->pwm_suspend_vol = be32_to_cpu(*suspend_vol);\r
237 \r
238         coefficient  = of_get_property(np, "rockchip,pwm_coefficient", NULL);\r
239         if (coefficient )\r
240                 pwm_plat_data->pwm_coefficient = be32_to_cpu(*coefficient );\r
241         \r
242         id  = of_get_property(np, "rockchip,pwm_id", NULL);\r
243         if (id )\r
244                 pwm_plat_data->pwm_id = be32_to_cpu(*id );\r
245 \r
246         prop = of_find_property(np, "rockchip,pwm_voltage_map", &length);\r
247         if (!prop)\r
248                 return NULL;\r
249         pwm_plat_data->pwm_vol_map_count = length / sizeof(u32);\r
250         if (pwm_plat_data->pwm_vol_map_count > 0) {\r
251                 size_t size = sizeof(*pwm_plat_data->pwm_voltage_map) * pwm_plat_data->pwm_vol_map_count;\r
252 \r
253         pwm_plat_data->pwm_voltage_map = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);\r
254         if (! pwm_plat_data->pwm_voltage_map)\r
255                 return NULL;\r
256         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
257         if (ret < 0)\r
258                 printk("pwm voltage map not specified\n");\r
259         }\r
260         return pwm_plat_data;\r
261 }\r
262 #else\r
263 static inline struct pwm_regulator_board *pwm_regulator_parse_dt(\r
264                         struct platform_device *pdev,\r
265                         struct of_regulator_match **pwm_reg_matches)\r
266 {\r
267         return NULL;\r
268 }\r
269 #endif\r
270 \r
271 \r
272 static int __init pwm_regulator_probe(struct platform_device *pdev)\r
273 {\r
274         struct pwm_platform_data *pdata = pdev->dev.platform_data;\r
275         struct pwm_regulator_board *pwm_pdev;\r
276         struct of_regulator_match *pwm_reg_matches = NULL;\r
277         struct regulator_init_data *reg_data;\r
278         struct regulator_config config = { };\r
279         const char *rail_name = NULL;\r
280         struct regulator_dev *pwm_rdev;\r
281         int ret,i=0;\r
282         struct regulator *dc;\r
283 \r
284         pwm_pdev = devm_kzalloc(&pdev->dev, sizeof(*pwm_pdev),\r
285                                         GFP_KERNEL);\r
286         pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata),\r
287                                         GFP_KERNEL);\r
288         \r
289         if (pdev->dev.of_node)\r
290                 pwm_pdev = pwm_regulator_parse_dt(pdev,&pwm_reg_matches);\r
291 \r
292         if (!pwm_pdev) {\r
293                 dev_err(&pdev->dev, "Platform data not found\n");\r
294                 return -EINVAL;\r
295         }\r
296         \r
297         if (!pwm_pdev->pwm_init_vol)\r
298                 pdata->pwm_voltage = 1100000;   // default 1.1v\r
299         else\r
300                 pdata->pwm_voltage = pwm_pdev->pwm_init_vol;    \r
301 \r
302         if(!pwm_pdev->pwm_max_vol)\r
303                 pdata->max_uV = 1400000;\r
304         else\r
305                 pdata->max_uV = pwm_pdev->pwm_max_vol;\r
306 \r
307         if(!pwm_pdev->pwm_min_vol)\r
308                 pdata->min_uV = 1000000;\r
309         else\r
310                 pdata->min_uV = pwm_pdev->pwm_min_vol;\r
311 \r
312         if(pwm_pdev->pwm_suspend_vol < pwm_pdev->pwm_min_vol)\r
313                 pdata->suspend_voltage = pwm_pdev->pwm_min_vol;\r
314         else if(pwm_pdev->pwm_suspend_vol > pwm_pdev->pwm_max_vol)\r
315                 pdata->suspend_voltage = pwm_pdev->pwm_max_vol;\r
316         else\r
317                 pdata->suspend_voltage = pwm_pdev->pwm_suspend_vol;\r
318         \r
319         pdata->pwm_voltage_map = pwm_pdev->pwm_voltage_map;\r
320         pdata->pwm_id = pwm_pdev->pwm_id;\r
321         pdata->coefficient = pwm_pdev->pwm_coefficient;\r
322         pdata->pwm_vol_map_count = pwm_pdev->pwm_vol_map_count;\r
323         \r
324         pdata->pwm = devm_pwm_get(&pdev->dev, NULL);\r
325         if (IS_ERR(pdata->pwm)) {\r
326                 dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");\r
327 \r
328                 pdata->pwm = pwm_request(pdata->pwm_id, "pwm-regulator");\r
329                 if (IS_ERR(pdata->pwm)) {\r
330                         dev_err(&pdev->dev, "unable to request legacy PWM\n");\r
331                         ret = PTR_ERR(pdata->pwm);\r
332                         goto err;\r
333                 }\r
334         }\r
335         if (pdata->pwm_period_ns > 0)\r
336                 pwm_set_period(pdata->pwm, pdata->pwm_period_ns);\r
337 \r
338         pdata->period = pwm_get_period(pdata->pwm);\r
339 \r
340         g_pdata = pdata;\r
341         \r
342         if (pwm_pdev){\r
343                 pdata->num_regulators = pwm_pdev ->num_regulators;\r
344                 pdata->rdev = kcalloc(pdata->num_regulators,sizeof(struct regulator_dev *), GFP_KERNEL);\r
345                 if (!pdata->rdev) {\r
346                         return -ENOMEM;\r
347                 }\r
348                 /* Instantiate the regulators */\r
349                 for (i = 0; i < pdata->num_regulators; i++) {\r
350                 reg_data = pwm_pdev->pwm_init_data[i];\r
351                 if (!reg_data)\r
352                         continue;\r
353                 config.dev = &pdev->dev;\r
354                 config.driver_data = pdata;\r
355                 if (&pdev->dev.of_node)\r
356                         config.of_node = pwm_pdev->of_node[i];\r
357                 if (reg_data && reg_data->constraints.name)\r
358                                 rail_name = reg_data->constraints.name;\r
359                         else\r
360                                 rail_name = regulators[i].name;\r
361                         reg_data->supply_regulator = rail_name;\r
362         \r
363                 config.init_data =reg_data;\r
364 \r
365                 pwm_rdev = regulator_register(&regulators[i],&config);\r
366                 if (IS_ERR(pwm_rdev)) {\r
367                         printk("failed to register %d regulator\n",i);\r
368                 goto err;\r
369                 }\r
370                 pdata->rdev[i] = pwm_rdev;\r
371                 \r
372                 /*********set pwm vol by defult***********/\r
373                 dc = regulator_get(NULL,rail_name);\r
374                 regulator_set_voltage(dc,pdata->pwm_voltage,pdata->pwm_voltage);\r
375                 regulator_put(dc);\r
376                 /**************************************/\r
377                 }\r
378         }\r
379         return 0;\r
380 err:\r
381         printk("%s:error\n",__func__);\r
382         return ret;\r
383 \r
384 }\r
385 \r
386 void pwm_suspend_voltage(void)\r
387 {\r
388         \r
389 }\r
390 \r
391 void pwm_resume_voltage(void)\r
392 {\r
393 \r
394 }\r
395 \r
396 static int pwm_regulator_remove(struct platform_device *pdev)\r
397 {\r
398         struct pwm_platform_data *pdata = pdev->dev.platform_data;\r
399         int i;\r
400 \r
401         for (i = 0; i < pdata->num_regulators; i++)\r
402                 if (pdata->rdev[i])\r
403                         regulator_unregister(pdata->rdev[i]);\r
404         kfree(pdata->rdev);\r
405         return 0;\r
406 }\r
407 \r
408 static struct platform_driver pwm_regulator_driver = {\r
409         .driver = {\r
410                 .name = "pwm-voltage-regulator",\r
411                 .of_match_table =of_match_ptr(pwm_of_match),\r
412         },\r
413         .remove = pwm_regulator_remove,\r
414 };\r
415 \r
416 \r
417 static int __init pwm_regulator_module_init(void)\r
418 {\r
419         return platform_driver_probe(&pwm_regulator_driver, pwm_regulator_probe);\r
420 }\r
421 \r
422 static void __exit pwm_regulator_module_exit(void)\r
423 {\r
424         platform_driver_unregister(&pwm_regulator_driver);\r
425 }\r
426 \r
427 //fs_initcall(pwm_regulator_module_init);\r
428 module_init(pwm_regulator_module_init);\r
429 module_exit(pwm_regulator_module_exit);\r
430 MODULE_LICENSE("GPL");\r