hi6421-pmic-core.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Device driver for Hi6421 PMIC
  3. *
  4. * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
  5. * http://www.hisilicon.com
  6. * Copyright (c) <2013-2017> Linaro Ltd.
  7. * http://www.linaro.org
  8. *
  9. * Author: Guodong Xu <guodong.xu@linaro.org>
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License version 2 as
  13. * published by the Free Software Foundation.
  14. */
  15. #include <linux/device.h>
  16. #include <linux/err.h>
  17. #include <linux/mfd/core.h>
  18. #include <linux/mfd/hi6421-pmic.h>
  19. #include <linux/module.h>
  20. #include <linux/of_device.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/regmap.h>
  23. static const struct mfd_cell hi6421_devs[] = {
  24. { .name = "hi6421-regulator", },
  25. };
  26. static const struct mfd_cell hi6421v530_devs[] = {
  27. { .name = "hi6421v530-regulator", },
  28. };
  29. static const struct regmap_config hi6421_regmap_config = {
  30. .reg_bits = 32,
  31. .reg_stride = 4,
  32. .val_bits = 8,
  33. .max_register = HI6421_REG_TO_BUS_ADDR(HI6421_REG_MAX),
  34. };
  35. static const struct of_device_id of_hi6421_pmic_match[] = {
  36. {
  37. .compatible = "hisilicon,hi6421-pmic",
  38. .data = (void *)HI6421
  39. },
  40. {
  41. .compatible = "hisilicon,hi6421v530-pmic",
  42. .data = (void *)HI6421_V530
  43. },
  44. { },
  45. };
  46. MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match);
  47. static int hi6421_pmic_probe(struct platform_device *pdev)
  48. {
  49. struct hi6421_pmic *pmic;
  50. struct resource *res;
  51. const struct of_device_id *id;
  52. const struct mfd_cell *subdevs;
  53. enum hi6421_type type;
  54. void __iomem *base;
  55. int n_subdevs, ret;
  56. id = of_match_device(of_hi6421_pmic_match, &pdev->dev);
  57. if (!id)
  58. return -EINVAL;
  59. type = (enum hi6421_type)id->data;
  60. pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
  61. if (!pmic)
  62. return -ENOMEM;
  63. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  64. base = devm_ioremap_resource(&pdev->dev, res);
  65. if (IS_ERR(base))
  66. return PTR_ERR(base);
  67. pmic->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
  68. &hi6421_regmap_config);
  69. if (IS_ERR(pmic->regmap)) {
  70. dev_err(&pdev->dev, "Failed to initialise Regmap: %ld\n",
  71. PTR_ERR(pmic->regmap));
  72. return PTR_ERR(pmic->regmap);
  73. }
  74. platform_set_drvdata(pdev, pmic);
  75. switch (type) {
  76. case HI6421:
  77. /* set over-current protection debounce 8ms */
  78. regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG,
  79. (HI6421_OCP_DEB_SEL_MASK
  80. | HI6421_OCP_EN_DEBOUNCE_MASK
  81. | HI6421_OCP_AUTO_STOP_MASK),
  82. (HI6421_OCP_DEB_SEL_8MS
  83. | HI6421_OCP_EN_DEBOUNCE_ENABLE));
  84. subdevs = hi6421_devs;
  85. n_subdevs = ARRAY_SIZE(hi6421_devs);
  86. break;
  87. case HI6421_V530:
  88. subdevs = hi6421v530_devs;
  89. n_subdevs = ARRAY_SIZE(hi6421v530_devs);
  90. break;
  91. default:
  92. dev_err(&pdev->dev, "Unknown device type %d\n",
  93. (unsigned int)type);
  94. return -EINVAL;
  95. }
  96. ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
  97. subdevs, n_subdevs, NULL, 0, NULL);
  98. if (ret) {
  99. dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret);
  100. return ret;
  101. }
  102. return 0;
  103. }
  104. static struct platform_driver hi6421_pmic_driver = {
  105. .driver = {
  106. .name = "hi6421_pmic",
  107. .of_match_table = of_hi6421_pmic_match,
  108. },
  109. .probe = hi6421_pmic_probe,
  110. };
  111. module_platform_driver(hi6421_pmic_driver);
  112. MODULE_AUTHOR("Guodong Xu <guodong.xu@linaro.org>");
  113. MODULE_DESCRIPTION("Hi6421 PMIC driver");
  114. MODULE_LICENSE("GPL v2");