anatop-mfd.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * Anatop MFD driver
  3. *
  4. * Copyright (C) 2012 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
  5. * Copyright (C) 2012 Linaro
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. * This program is free software; you can redistribute it and/or modify
  21. * it under the terms of the GNU General Public License as published by
  22. * the Free Software Foundation; either version 2 of the License, or
  23. * (at your option) any later version.
  24. *
  25. * This program is distributed in the hope that it will be useful,
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28. * GNU General Public License for more details.
  29. *
  30. * You should have received a copy of the GNU General Public License along
  31. * with this program; if not, write to the Free Software Foundation, Inc.,
  32. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  33. *
  34. */
  35. #include <linux/io.h>
  36. #include <linux/module.h>
  37. #include <linux/platform_device.h>
  38. #include <linux/of.h>
  39. #include <linux/of_platform.h>
  40. #include <linux/of_address.h>
  41. #include <linux/mfd/anatop.h>
  42. u32 anatop_get_bits(struct anatop *adata, u32 addr, int bit_shift,
  43. int bit_width)
  44. {
  45. u32 val, mask;
  46. if (bit_width == 32)
  47. mask = ~0;
  48. else
  49. mask = (1 << bit_width) - 1;
  50. val = readl(adata->ioreg + addr);
  51. val = (val >> bit_shift) & mask;
  52. return val;
  53. }
  54. EXPORT_SYMBOL_GPL(anatop_get_bits);
  55. void anatop_set_bits(struct anatop *adata, u32 addr, int bit_shift,
  56. int bit_width, u32 data)
  57. {
  58. u32 val, mask;
  59. if (bit_width == 32)
  60. mask = ~0;
  61. else
  62. mask = (1 << bit_width) - 1;
  63. spin_lock(&adata->reglock);
  64. val = readl(adata->ioreg + addr) & ~(mask << bit_shift);
  65. writel((data << bit_shift) | val, adata->ioreg + addr);
  66. spin_unlock(&adata->reglock);
  67. }
  68. EXPORT_SYMBOL_GPL(anatop_set_bits);
  69. static const struct of_device_id of_anatop_match[] = {
  70. { .compatible = "fsl,imx6q-anatop", },
  71. { },
  72. };
  73. static int __devinit of_anatop_probe(struct platform_device *pdev)
  74. {
  75. struct device *dev = &pdev->dev;
  76. struct device_node *np = dev->of_node;
  77. void *ioreg;
  78. struct anatop *drvdata;
  79. ioreg = of_iomap(np, 0);
  80. if (!ioreg)
  81. return -EADDRNOTAVAIL;
  82. drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
  83. if (!drvdata)
  84. return -ENOMEM;
  85. drvdata->ioreg = ioreg;
  86. spin_lock_init(&drvdata->reglock);
  87. platform_set_drvdata(pdev, drvdata);
  88. of_platform_populate(np, of_anatop_match, NULL, dev);
  89. return 0;
  90. }
  91. static int __devexit of_anatop_remove(struct platform_device *pdev)
  92. {
  93. struct anatop *drvdata;
  94. drvdata = platform_get_drvdata(pdev);
  95. iounmap(drvdata->ioreg);
  96. return 0;
  97. }
  98. static struct platform_driver anatop_of_driver = {
  99. .driver = {
  100. .name = "anatop-mfd",
  101. .owner = THIS_MODULE,
  102. .of_match_table = of_anatop_match,
  103. },
  104. .probe = of_anatop_probe,
  105. .remove = of_anatop_remove,
  106. };
  107. static int __init anatop_init(void)
  108. {
  109. return platform_driver_register(&anatop_of_driver);
  110. }
  111. postcore_initcall(anatop_init);
  112. static void __exit anatop_exit(void)
  113. {
  114. platform_driver_unregister(&anatop_of_driver);
  115. }
  116. module_exit(anatop_exit);
  117. MODULE_AUTHOR("Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>");
  118. MODULE_DESCRIPTION("ANATOP MFD driver");
  119. MODULE_LICENSE("GPL v2");