ab8500-pwm.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright (C) ST-Ericsson SA 2010
  3. *
  4. * Author: Arun R Murthy <arun.murthy@stericsson.com>
  5. * License terms: GNU General Public License (GPL) version 2
  6. */
  7. #include <linux/err.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/slab.h>
  10. #include <linux/pwm.h>
  11. #include <linux/mfd/abx500.h>
  12. #include <linux/mfd/abx500/ab8500.h>
  13. #include <linux/module.h>
  14. /*
  15. * PWM Out generators
  16. * Bank: 0x10
  17. */
  18. #define AB8500_PWM_OUT_CTRL1_REG 0x60
  19. #define AB8500_PWM_OUT_CTRL2_REG 0x61
  20. #define AB8500_PWM_OUT_CTRL7_REG 0x66
  21. /* backlight driver constants */
  22. #define ENABLE_PWM 1
  23. #define DISABLE_PWM 0
  24. struct pwm_device {
  25. struct device *dev;
  26. struct list_head node;
  27. const char *label;
  28. unsigned int pwm_id;
  29. };
  30. static LIST_HEAD(pwm_list);
  31. int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
  32. {
  33. int ret = 0;
  34. unsigned int higher_val, lower_val;
  35. u8 reg;
  36. /*
  37. * get the first 8 bits that are be written to
  38. * AB8500_PWM_OUT_CTRL1_REG[0:7]
  39. */
  40. lower_val = duty_ns & 0x00FF;
  41. /*
  42. * get bits [9:10] that are to be written to
  43. * AB8500_PWM_OUT_CTRL2_REG[0:1]
  44. */
  45. higher_val = ((duty_ns & 0x0300) >> 8);
  46. reg = AB8500_PWM_OUT_CTRL1_REG + ((pwm->pwm_id - 1) * 2);
  47. ret = abx500_set_register_interruptible(pwm->dev, AB8500_MISC,
  48. reg, (u8)lower_val);
  49. if (ret < 0)
  50. return ret;
  51. ret = abx500_set_register_interruptible(pwm->dev, AB8500_MISC,
  52. (reg + 1), (u8)higher_val);
  53. return ret;
  54. }
  55. EXPORT_SYMBOL(pwm_config);
  56. int pwm_enable(struct pwm_device *pwm)
  57. {
  58. int ret;
  59. ret = abx500_mask_and_set_register_interruptible(pwm->dev,
  60. AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
  61. 1 << (pwm->pwm_id-1), ENABLE_PWM);
  62. if (ret < 0)
  63. dev_err(pwm->dev, "%s: Failed to disable PWM, Error %d\n",
  64. pwm->label, ret);
  65. return ret;
  66. }
  67. EXPORT_SYMBOL(pwm_enable);
  68. void pwm_disable(struct pwm_device *pwm)
  69. {
  70. int ret;
  71. ret = abx500_mask_and_set_register_interruptible(pwm->dev,
  72. AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
  73. 1 << (pwm->pwm_id-1), DISABLE_PWM);
  74. if (ret < 0)
  75. dev_err(pwm->dev, "%s: Failed to disable PWM, Error %d\n",
  76. pwm->label, ret);
  77. return;
  78. }
  79. EXPORT_SYMBOL(pwm_disable);
  80. struct pwm_device *pwm_request(int pwm_id, const char *label)
  81. {
  82. struct pwm_device *pwm;
  83. list_for_each_entry(pwm, &pwm_list, node) {
  84. if (pwm->pwm_id == pwm_id) {
  85. pwm->label = label;
  86. pwm->pwm_id = pwm_id;
  87. return pwm;
  88. }
  89. }
  90. return ERR_PTR(-ENOENT);
  91. }
  92. EXPORT_SYMBOL(pwm_request);
  93. void pwm_free(struct pwm_device *pwm)
  94. {
  95. pwm_disable(pwm);
  96. }
  97. EXPORT_SYMBOL(pwm_free);
  98. static int __devinit ab8500_pwm_probe(struct platform_device *pdev)
  99. {
  100. struct pwm_device *pwm;
  101. /*
  102. * Nothing to be done in probe, this is required to get the
  103. * device which is required for ab8500 read and write
  104. */
  105. pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
  106. if (pwm == NULL) {
  107. dev_err(&pdev->dev, "failed to allocate memory\n");
  108. return -ENOMEM;
  109. }
  110. pwm->dev = &pdev->dev;
  111. pwm->pwm_id = pdev->id;
  112. list_add_tail(&pwm->node, &pwm_list);
  113. platform_set_drvdata(pdev, pwm);
  114. dev_dbg(pwm->dev, "pwm probe successful\n");
  115. return 0;
  116. }
  117. static int __devexit ab8500_pwm_remove(struct platform_device *pdev)
  118. {
  119. struct pwm_device *pwm = platform_get_drvdata(pdev);
  120. list_del(&pwm->node);
  121. dev_dbg(&pdev->dev, "pwm driver removed\n");
  122. kfree(pwm);
  123. return 0;
  124. }
  125. static struct platform_driver ab8500_pwm_driver = {
  126. .driver = {
  127. .name = "ab8500-pwm",
  128. .owner = THIS_MODULE,
  129. },
  130. .probe = ab8500_pwm_probe,
  131. .remove = __devexit_p(ab8500_pwm_remove),
  132. };
  133. static int __init ab8500_pwm_init(void)
  134. {
  135. return platform_driver_register(&ab8500_pwm_driver);
  136. }
  137. static void __exit ab8500_pwm_exit(void)
  138. {
  139. platform_driver_unregister(&ab8500_pwm_driver);
  140. }
  141. subsys_initcall(ab8500_pwm_init);
  142. module_exit(ab8500_pwm_exit);
  143. MODULE_AUTHOR("Arun MURTHY <arun.murthy@stericsson.com>");
  144. MODULE_DESCRIPTION("AB8500 Pulse Width Modulation Driver");
  145. MODULE_ALIAS("platform:ab8500-pwm");
  146. MODULE_LICENSE("GPL v2");