88pm860x-core.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Base driver for Marvell 88PM8607
  3. *
  4. * Copyright (C) 2009 Marvell International Ltd.
  5. * Haojian Zhuang <haojian.zhuang@marvell.com>
  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 version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/mfd/core.h>
  16. #include <linux/mfd/88pm8607.h>
  17. #define PM8607_REG_RESOURCE(_start, _end) \
  18. { \
  19. .start = PM8607_##_start, \
  20. .end = PM8607_##_end, \
  21. .flags = IORESOURCE_IO, \
  22. }
  23. static struct resource pm8607_regulator_resources[] = {
  24. PM8607_REG_RESOURCE(BUCK1, BUCK1),
  25. PM8607_REG_RESOURCE(BUCK2, BUCK2),
  26. PM8607_REG_RESOURCE(BUCK3, BUCK3),
  27. PM8607_REG_RESOURCE(LDO1, LDO1),
  28. PM8607_REG_RESOURCE(LDO2, LDO2),
  29. PM8607_REG_RESOURCE(LDO3, LDO3),
  30. PM8607_REG_RESOURCE(LDO4, LDO4),
  31. PM8607_REG_RESOURCE(LDO5, LDO5),
  32. PM8607_REG_RESOURCE(LDO6, LDO6),
  33. PM8607_REG_RESOURCE(LDO7, LDO7),
  34. PM8607_REG_RESOURCE(LDO8, LDO8),
  35. PM8607_REG_RESOURCE(LDO9, LDO9),
  36. PM8607_REG_RESOURCE(LDO10, LDO10),
  37. PM8607_REG_RESOURCE(LDO12, LDO12),
  38. PM8607_REG_RESOURCE(LDO14, LDO14),
  39. };
  40. #define PM8607_REG_DEVS(_name, _id) \
  41. { \
  42. .name = "88pm8607-" #_name, \
  43. .num_resources = 1, \
  44. .resources = &pm8607_regulator_resources[PM8607_ID_##_id], \
  45. }
  46. static struct mfd_cell pm8607_devs[] = {
  47. PM8607_REG_DEVS(buck1, BUCK1),
  48. PM8607_REG_DEVS(buck2, BUCK2),
  49. PM8607_REG_DEVS(buck3, BUCK3),
  50. PM8607_REG_DEVS(ldo1, LDO1),
  51. PM8607_REG_DEVS(ldo2, LDO2),
  52. PM8607_REG_DEVS(ldo3, LDO3),
  53. PM8607_REG_DEVS(ldo4, LDO4),
  54. PM8607_REG_DEVS(ldo5, LDO5),
  55. PM8607_REG_DEVS(ldo6, LDO6),
  56. PM8607_REG_DEVS(ldo7, LDO7),
  57. PM8607_REG_DEVS(ldo8, LDO8),
  58. PM8607_REG_DEVS(ldo9, LDO9),
  59. PM8607_REG_DEVS(ldo10, LDO10),
  60. PM8607_REG_DEVS(ldo12, LDO12),
  61. PM8607_REG_DEVS(ldo14, LDO14),
  62. };
  63. int pm860x_device_init(struct pm8607_chip *chip,
  64. struct pm8607_platform_data *pdata)
  65. {
  66. int i, count;
  67. int ret;
  68. ret = pm8607_reg_read(chip, PM8607_CHIP_ID);
  69. if (ret < 0) {
  70. dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
  71. goto out;
  72. }
  73. if ((ret & PM8607_ID_MASK) == PM8607_ID)
  74. dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
  75. ret);
  76. else {
  77. dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
  78. "Chip ID: %02x\n", ret);
  79. goto out;
  80. }
  81. chip->chip_id = ret;
  82. ret = pm8607_reg_read(chip, PM8607_BUCK3);
  83. if (ret < 0) {
  84. dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret);
  85. goto out;
  86. }
  87. if (ret & PM8607_BUCK3_DOUBLE)
  88. chip->buck3_double = 1;
  89. ret = pm8607_reg_read(chip, PM8607_MISC1);
  90. if (ret < 0) {
  91. dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret);
  92. goto out;
  93. }
  94. if (pdata->i2c_port == PI2C_PORT)
  95. ret |= PM8607_MISC1_PI2C;
  96. else
  97. ret &= ~PM8607_MISC1_PI2C;
  98. ret = pm8607_reg_write(chip, PM8607_MISC1, ret);
  99. if (ret < 0) {
  100. dev_err(chip->dev, "Failed to write MISC1 register: %d\n", ret);
  101. goto out;
  102. }
  103. count = ARRAY_SIZE(pm8607_devs);
  104. for (i = 0; i < count; i++) {
  105. ret = mfd_add_devices(chip->dev, i, &pm8607_devs[i],
  106. 1, NULL, 0);
  107. if (ret != 0) {
  108. dev_err(chip->dev, "Failed to add subdevs\n");
  109. goto out;
  110. }
  111. }
  112. out:
  113. return ret;
  114. }
  115. void pm8607_device_exit(struct pm8607_chip *chip)
  116. {
  117. mfd_remove_devices(chip->dev);
  118. }
  119. MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM8607");
  120. MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
  121. MODULE_LICENSE("GPL");