blob: 031f5e1c3acf24b0c8def932051562a35f93fa9c [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13/*
14 * msm_dsps - control DSPS clocks, gpios and vregs.
15 *
16 */
17
18#include <linux/types.h>
19#include <linux/slab.h>
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/cdev.h>
23#include <linux/fs.h>
24#include <linux/platform_device.h>
25#include <linux/err.h>
26#include <linux/delay.h>
27#include <linux/clk.h>
28#include <linux/gpio.h>
29#include <linux/string.h>
30#include <linux/uaccess.h>
31#include <linux/io.h>
32#include <linux/msm_dsps.h>
33
34#include <mach/peripheral-loader.h>
35#include <mach/msm_iomap.h>
36#include <mach/msm_dsps.h>
37
38#define DRV_NAME "msm_dsps"
39#define DRV_VERSION "2.00"
40
41#define PPSS_PAUSE_REG 0x1804
42
43#define PPSS_TIMER0_32KHZ_REG 0x1004
44#define PPSS_TIMER0_20MHZ_REG 0x0804
45
46/**
47 * Driver Context
48 *
49 * @dev_class - device class.
50 * @dev_num - device major & minor number.
51 * @dev - the device.
52 * @cdev - character device for user interface.
53 * @pdata - platform data.
54 * @pil - handle to DSPS Firmware loader.
55 * @is_on - DSPS is on.
56 * @ref_count - open/close reference count.
57 * @ppss_base - ppss registers virtual base address.
58 */
59struct dsps_drv {
60
61 struct class *dev_class;
62 dev_t dev_num;
63 struct device *dev;
64 struct cdev *cdev;
65
66 struct msm_dsps_platform_data *pdata;
67
68 void *pil;
69
70 int is_on;
71 int ref_count;
72
73 void __iomem *ppss_base;
74};
75
76/**
77 * Driver context.
78 */
79static struct dsps_drv *drv;
80
81/**
82 * Load DSPS Firmware.
83 */
84static int dsps_load(const char *name)
85{
86 pr_debug("%s.\n", __func__);
87
88 drv->pil = pil_get(name);
89
90 if (IS_ERR(drv->pil)) {
91 pr_err("%s: fail to load DSPS firmware %s.\n", __func__, name);
92 return -ENODEV;
93 }
94
95 return 0;
96}
97
98/**
99 * Unload DSPS Firmware.
100 */
101static void dsps_unload(void)
102{
103 pr_debug("%s.\n", __func__);
104
105 pil_put(drv->pil);
106}
107
108/**
109 * Suspend DSPS CPU.
110 */
111static void dsps_suspend(void)
112{
113 pr_debug("%s.\n", __func__);
114
115 writel_relaxed(1, drv->ppss_base + PPSS_PAUSE_REG);
116 mb(); /* Make sure write commited before ioctl returns. */
117}
118
119/**
120 * Resume DSPS CPU.
121 */
122static void dsps_resume(void)
123{
124 pr_debug("%s.\n", __func__);
125
126 writel_relaxed(0, drv->ppss_base + PPSS_PAUSE_REG);
127 mb(); /* Make sure write commited before ioctl returns. */
128}
129
130/**
131 * Read DSPS slow timer.
132 */
133static u32 dsps_read_slow_timer(void)
134{
135 u32 val;
136
137 val = readl_relaxed(drv->ppss_base + PPSS_TIMER0_32KHZ_REG);
138 rmb(); /* order reads from the user output buffer */
139
140 pr_debug("%s.count=%d.\n", __func__, val);
141
142 return val;
143}
144
145/**
146 * Read DSPS fast timer.
147 */
148static u32 dsps_read_fast_timer(void)
149{
150 u32 val;
151
152 val = readl_relaxed(drv->ppss_base + PPSS_TIMER0_20MHZ_REG);
153 rmb(); /* order reads from the user output buffer */
154
155 pr_debug("%s.count=%d.\n", __func__, val);
156
157 return val;
158}
159
160/**
161 * Power on request.
162 *
163 * Set clocks to ON.
164 * Set sensors chip-select GPIO to non-reset (on) value.
165 *
166 */
167static int dsps_power_on_handler(void)
168{
169 int ret = 0;
170 int i, ci, gi, ri;
171
172 pr_debug("%s.\n", __func__);
173
174 if (drv->is_on) {
175 pr_debug("%s: already ON.\n", __func__);
176 return 0;
177 }
178
179 for (ci = 0; ci < drv->pdata->clks_num; ci++) {
180 const char *name = drv->pdata->clks[ci].name;
181 u32 rate = drv->pdata->clks[ci].rate;
182 struct clk *clock = drv->pdata->clks[ci].clock;
183
184 if (clock == NULL)
185 continue;
186
187 if (rate > 0) {
188 ret = clk_set_rate(clock, rate);
189 pr_debug("%s: clk %s set rate %d.",
190 __func__, name, rate);
191 if (ret) {
192 pr_err("%s: clk %s set rate %d. err=%d.",
193 __func__, name, rate, ret);
194 goto clk_err;
195 }
196
197 }
198
199 ret = clk_enable(clock);
200 if (ret) {
201 pr_err("%s: enable clk %s err %d.",
202 __func__, name, ret);
203 goto clk_err;
204 }
205 }
206
207 for (gi = 0; gi < drv->pdata->gpios_num; gi++) {
208 const char *name = drv->pdata->gpios[gi].name;
209 int num = drv->pdata->gpios[gi].num;
210 int val = drv->pdata->gpios[gi].on_val;
211 int is_owner = drv->pdata->gpios[gi].is_owner;
212
213 if (!is_owner)
214 continue;
215
216 ret = gpio_direction_output(num, val);
217 if (ret) {
218 pr_err("%s: set GPIO %s num %d to %d err %d.",
219 __func__, name, num, val, ret);
220 goto gpio_err;
221 }
222 }
223
224 for (ri = 0; ri < drv->pdata->regs_num; ri++) {
225 const char *name = drv->pdata->regs[ri].name;
226 struct regulator *reg = drv->pdata->regs[ri].reg;
227 int volt = drv->pdata->regs[ri].volt;
228
229 if (reg == NULL)
230 continue;
231
232 pr_debug("%s: set regulator %s.", __func__, name);
233
234 ret = regulator_set_voltage(reg, volt, volt);
235
236 if (ret) {
237 pr_err("%s: set regulator %s voltage %d err = %d.\n",
238 __func__, name, volt, ret);
239 goto reg_err;
240 }
241
242 ret = regulator_enable(reg);
243 if (ret) {
244 pr_err("%s: enable regulator %s err = %d.\n",
245 __func__, name, ret);
246 goto reg_err;
247 }
248 }
249
250 drv->is_on = true;
251
252 return 0;
253
254 /*
255 * If failling to set ANY clock/gpio/regulator to ON then we set
256 * them back to OFF to avoid consuming power for unused
257 * clocks/gpios/regulators.
258 */
259reg_err:
260 for (i = 0; i < ri; i++) {
261 struct regulator *reg = drv->pdata->regs[ri].reg;
262
263 if (reg == NULL)
264 continue;
265
266 regulator_disable(reg);
267 }
268
269gpio_err:
270 for (i = 0; i < gi; i++) {
271 int num = drv->pdata->gpios[i].num;
272 int val = drv->pdata->gpios[i].off_val;
273 int is_owner = drv->pdata->gpios[i].is_owner;
274
275 if (!is_owner)
276 continue;
277
278 ret = gpio_direction_output(num, val);
279 }
280
281clk_err:
282 for (i = 0; i < ci; i++) {
283 struct clk *clock = drv->pdata->clks[i].clock;
284
285 if (clock == NULL)
286 continue;
287
288 clk_disable(clock);
289 }
290
291 return -ENODEV;
292}
293
294/**
295 * Power off request.
296 *
297 * Set clocks to OFF.
298 * Set sensors chip-select GPIO to reset (off) value.
299 *
300 */
301static int dsps_power_off_handler(void)
302{
303 int ret;
304 int i;
305
306 pr_debug("%s.\n", __func__);
307
308 if (!drv->is_on) {
309 pr_debug("%s: already OFF.\n", __func__);
310 return 0;
311 }
312
313 for (i = 0; i < drv->pdata->clks_num; i++)
314 if (drv->pdata->clks[i].clock) {
315 const char *name = drv->pdata->clks[i].name;
316
317 pr_debug("%s: set clk %s off.", __func__, name);
318 clk_disable(drv->pdata->clks[i].clock);
319 }
320
321 for (i = 0; i < drv->pdata->regs_num; i++)
322 if (drv->pdata->regs[i].reg) {
323 const char *name = drv->pdata->regs[i].name;
324
325 pr_debug("%s: set regulator %s off.", __func__, name);
326 regulator_disable(drv->pdata->regs[i].reg);
327 }
328
329 /* Clocks on/off has reference count but GPIOs don't. */
330 drv->is_on = false;
331
332 for (i = 0; i < drv->pdata->gpios_num; i++) {
333 const char *name = drv->pdata->gpios[i].name;
334 int num = drv->pdata->gpios[i].num;
335 int val = drv->pdata->gpios[i].off_val;
336
337 pr_debug("%s: set gpio %s off.", __func__, name);
338
339 ret = gpio_direction_output(num, val);
340 if (ret) {
341 pr_err("%s: set GPIO %s err %d.", __func__, name, ret);
342 return ret;
343 }
344 }
345
346 return 0;
347}
348
349/**
350 * IO Control - handle commands from client.
351 *
352 */
353static long dsps_ioctl(struct file *file,
354 unsigned int cmd, unsigned long arg)
355{
356 int ret = 0;
357 u32 val = 0;
358
359 pr_debug("%s.\n", __func__);
360
361 switch (cmd) {
362 case DSPS_IOCTL_ON:
363 ret = dsps_power_on_handler();
364 dsps_resume();
365 break;
366 case DSPS_IOCTL_OFF:
367 if (!drv->pdata->dsps_pwr_ctl_en) {
368 dsps_suspend();
369 ret = dsps_power_off_handler();
370 }
371 break;
372 case DSPS_IOCTL_READ_SLOW_TIMER:
373 val = dsps_read_slow_timer();
374 ret = put_user(val, (u32 __user *) arg);
375 break;
376 case DSPS_IOCTL_READ_FAST_TIMER:
377 val = dsps_read_fast_timer();
378 ret = put_user(val, (u32 __user *) arg);
379 break;
380 default:
381 ret = -EINVAL;
382 break;
383 }
384
385 return ret;
386}
387
388/**
389 * allocate resources.
390 * @pdev - pointer to platform device.
391 */
392static int dsps_alloc_resources(struct platform_device *pdev)
393{
394 int ret = -ENODEV;
395 struct resource *ppss_res;
396 int i;
397
398 pr_debug("%s.\n", __func__);
399
400 if ((drv->pdata->signature != DSPS_SIGNATURE)) {
401 pr_err("%s: invalid signature for pdata.", __func__);
402 return -EINVAL;
403 }
404
405 ppss_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
406 "ppss_reg");
407 if (!ppss_res) {
408 pr_err("%s: failed to get ppss_reg resource.\n", __func__);
409 return -EINVAL;
410 }
411
412 for (i = 0; i < drv->pdata->clks_num; i++) {
413 const char *name = drv->pdata->clks[i].name;
414 struct clk *clock;
415
416 drv->pdata->clks[i].clock = NULL;
417
418 pr_debug("%s: get clk %s.", __func__, name);
419
420 clock = clk_get(drv->dev, name);
421 if (IS_ERR(clock)) {
422 pr_err("%s: can't get clk %s.", __func__, name);
423 goto clk_err;
424 }
425 drv->pdata->clks[i].clock = clock;
426 }
427
428 for (i = 0; i < drv->pdata->gpios_num; i++) {
429 const char *name = drv->pdata->gpios[i].name;
430 int num = drv->pdata->gpios[i].num;
431
432 drv->pdata->gpios[i].is_owner = false;
433
434 pr_debug("%s: get gpio %s.", __func__, name);
435
436 ret = gpio_request(num, name);
437 if (ret) {
438 pr_err("%s: request GPIO %s err %d.",
439 __func__, name, ret);
440 goto gpio_err;
441 }
442
443 drv->pdata->gpios[i].is_owner = true;
444
445 }
446
447 for (i = 0; i < drv->pdata->regs_num; i++) {
448 const char *name = drv->pdata->regs[i].name;
449
450 drv->pdata->regs[i].reg = NULL;
451
452 pr_debug("%s: get regulator %s.", __func__, name);
453
454 drv->pdata->regs[i].reg = regulator_get(drv->dev, name);
455 if (IS_ERR(drv->pdata->regs[i].reg)) {
456 pr_err("%s: get regulator %s failed.",
457 __func__, name);
458 goto reg_err;
459 }
460 }
461
462 drv->ppss_base = ioremap(ppss_res->start,
463 resource_size(ppss_res));
464
465 return 0;
466
467reg_err:
468 for (i = 0; i < drv->pdata->regs_num; i++) {
469 if (drv->pdata->regs[i].reg) {
470 regulator_put(drv->pdata->regs[i].reg);
471 drv->pdata->regs[i].reg = NULL;
472 }
473 }
474
475gpio_err:
476 for (i = 0; i < drv->pdata->gpios_num; i++)
477 if (drv->pdata->gpios[i].is_owner) {
478 gpio_free(drv->pdata->gpios[i].num);
479 drv->pdata->gpios[i].is_owner = false;
480 }
481clk_err:
482 for (i = 0; i < drv->pdata->clks_num; i++)
483 if (drv->pdata->clks[i].clock) {
484 clk_put(drv->pdata->clks[i].clock);
485 drv->pdata->clks[i].clock = NULL;
486 }
487
488 return ret;
489}
490
491/**
492 * Open File.
493 *
494 */
495static int dsps_open(struct inode *ip, struct file *fp)
496{
497 int ret = 0;
498
499 pr_debug("%s.\n", __func__);
500
501 if (drv->ref_count == 0) {
502
503 /* clocks must be ON before loading.*/
504 ret = dsps_power_on_handler();
505 if (ret)
506 return ret;
507
508 ret = dsps_load(drv->pdata->pil_name);
509
510 if (ret) {
511 dsps_power_off_handler();
512 return ret;
513 }
514
515 dsps_resume();
516 }
517 drv->ref_count++;
518
519 return ret;
520}
521
522/**
523 * free resources.
524 *
525 */
526static void dsps_free_resources(void)
527{
528 int i;
529
530 pr_debug("%s.\n", __func__);
531
532 for (i = 0; i < drv->pdata->clks_num; i++)
533 if (drv->pdata->clks[i].clock) {
534 clk_put(drv->pdata->clks[i].clock);
535 drv->pdata->clks[i].clock = NULL;
536 }
537
538 for (i = 0; i < drv->pdata->gpios_num; i++)
539 if (drv->pdata->gpios[i].is_owner) {
540 gpio_free(drv->pdata->gpios[i].num);
541 drv->pdata->gpios[i].is_owner = false;
542 }
543
544 for (i = 0; i < drv->pdata->regs_num; i++) {
545 if (drv->pdata->regs[i].reg) {
546 regulator_put(drv->pdata->regs[i].reg);
547 drv->pdata->regs[i].reg = NULL;
548 }
549 }
550
551 iounmap(drv->ppss_base);
552}
553
554/**
555 * Close File.
556 *
557 * The client shall close and re-open the file for re-loading the DSPS
558 * firmware.
559 * The file system will close the file if the user space app has crashed.
560 *
561 * If the DSPS is running, then we must reset DSPS CPU & HW before
562 * setting the clocks off.
563 * The DSPS reset should be done as part of the pil_put().
564 * The DSPS reset should be used for error recovery if the DSPS firmware
565 * has crashed and re-loading the firmware is required.
566 */
567static int dsps_release(struct inode *inode, struct file *file)
568{
569 pr_debug("%s.\n", __func__);
570
571 drv->ref_count--;
572
573 if (drv->ref_count == 0) {
574 if (!drv->pdata->dsps_pwr_ctl_en) {
575 dsps_suspend();
576
577 dsps_unload();
578
579 dsps_power_off_handler();
580 }
581 }
582
583 return 0;
584}
585
586const struct file_operations dsps_fops = {
587 .owner = THIS_MODULE,
588 .open = dsps_open,
589 .release = dsps_release,
590 .unlocked_ioctl = dsps_ioctl,
591};
592
593/**
594 * platform driver
595 *
596 */
597static int __devinit dsps_probe(struct platform_device *pdev)
598{
599 int ret;
600
601 pr_debug("%s.\n", __func__);
602
603 if (pdev->dev.platform_data == NULL) {
604 pr_err("%s: platform data is NULL.\n", __func__);
605 return -ENODEV;
606 }
607
608 drv = kzalloc(sizeof(*drv), GFP_KERNEL);
609 if (drv == NULL) {
610 pr_err("%s: kzalloc fail.\n", __func__);
611 goto alloc_err;
612 }
613 drv->pdata = pdev->dev.platform_data;
614
615 ret = dsps_alloc_resources(pdev);
616 if (ret) {
617 pr_err("%s: failed to allocate dsps resources.\n", __func__);
618 goto res_err;
619 }
620
621 drv->dev_class = class_create(THIS_MODULE, DRV_NAME);
622 if (drv->dev_class == NULL) {
623 pr_err("%s: class_create fail.\n", __func__);
624 goto res_err;
625 }
626
627 ret = alloc_chrdev_region(&drv->dev_num, 0, 1, DRV_NAME);
628 if (ret) {
629 pr_err("%s: alloc_chrdev_region fail.\n", __func__);
630 goto alloc_chrdev_region_err;
631 }
632
633 drv->dev = device_create(drv->dev_class, NULL,
634 drv->dev_num,
635 drv, DRV_NAME);
636 if (IS_ERR(drv->dev)) {
637 pr_err("%s: device_create fail.\n", __func__);
638 goto device_create_err;
639 }
640
641 drv->cdev = cdev_alloc();
642 if (drv->cdev == NULL) {
643 pr_err("%s: cdev_alloc fail.\n", __func__);
644 goto cdev_alloc_err;
645 }
646 cdev_init(drv->cdev, &dsps_fops);
647 drv->cdev->owner = THIS_MODULE;
648
649 ret = cdev_add(drv->cdev, drv->dev_num, 1);
650 if (ret) {
651 pr_err("%s: cdev_add fail.\n", __func__);
652 goto cdev_add_err;
653 }
654
655 return 0;
656
657cdev_add_err:
658 kfree(drv->cdev);
659cdev_alloc_err:
660 device_destroy(drv->dev_class, drv->dev_num);
661device_create_err:
662 unregister_chrdev_region(drv->dev_num, 1);
663alloc_chrdev_region_err:
664 class_destroy(drv->dev_class);
665res_err:
666 kfree(drv);
667 drv = NULL;
668alloc_err:
669 return -ENODEV;
670}
671
672static int __devexit dsps_remove(struct platform_device *pdev)
673{
674 pr_debug("%s.\n", __func__);
675
676 dsps_power_off_handler();
677 dsps_free_resources();
678
679 cdev_del(drv->cdev);
680 kfree(drv->cdev);
681 drv->cdev = NULL;
682 device_destroy(drv->dev_class, drv->dev_num);
683 unregister_chrdev_region(drv->dev_num, 1);
684 class_destroy(drv->dev_class);
685 kfree(drv);
686 drv = NULL;
687
688 return 0;
689}
690
691static struct platform_driver dsps_driver = {
692 .probe = dsps_probe,
693 .remove = __exit_p(dsps_remove),
694 .driver = {
695 .name = "msm_dsps",
696 },
697};
698
699/**
700 * Module Init.
701 */
702static int __init dsps_init(void)
703{
704 int ret;
705
706 pr_info("%s driver version %s.\n", DRV_NAME, DRV_VERSION);
707
708 ret = platform_driver_register(&dsps_driver);
709
710 if (ret)
711 pr_err("dsps_init.err=%d.\n", ret);
712
713 return ret;
714}
715
716/**
717 * Module Exit.
718 */
719static void __exit dsps_exit(void)
720{
721 pr_debug("%s.\n", __func__);
722
723 platform_driver_unregister(&dsps_driver);
724}
725
726module_init(dsps_init);
727module_exit(dsps_exit);
728
729MODULE_LICENSE("GPL v2");
730MODULE_DESCRIPTION("Dedicated Sensors Processor Subsystem (DSPS) driver");
731MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
732