isl6271a-regulator.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * isl6271a-regulator.c
  4. *
  5. * Support for Intersil ISL6271A voltage regulator
  6. *
  7. * Copyright (C) 2010 Marek Vasut <[email protected]>
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/init.h>
  12. #include <linux/err.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/regulator/driver.h>
  15. #include <linux/i2c.h>
  16. #include <linux/slab.h>
  17. #define ISL6271A_VOLTAGE_MIN 850000
  18. #define ISL6271A_VOLTAGE_MAX 1600000
  19. #define ISL6271A_VOLTAGE_STEP 50000
  20. /* PMIC details */
  21. struct isl_pmic {
  22. struct i2c_client *client;
  23. struct mutex mtx;
  24. };
  25. static int isl6271a_get_voltage_sel(struct regulator_dev *dev)
  26. {
  27. struct isl_pmic *pmic = rdev_get_drvdata(dev);
  28. int idx;
  29. mutex_lock(&pmic->mtx);
  30. idx = i2c_smbus_read_byte(pmic->client);
  31. if (idx < 0)
  32. dev_err(&pmic->client->dev, "Error getting voltage\n");
  33. mutex_unlock(&pmic->mtx);
  34. return idx;
  35. }
  36. static int isl6271a_set_voltage_sel(struct regulator_dev *dev,
  37. unsigned selector)
  38. {
  39. struct isl_pmic *pmic = rdev_get_drvdata(dev);
  40. int err;
  41. mutex_lock(&pmic->mtx);
  42. err = i2c_smbus_write_byte(pmic->client, selector);
  43. if (err < 0)
  44. dev_err(&pmic->client->dev, "Error setting voltage\n");
  45. mutex_unlock(&pmic->mtx);
  46. return err;
  47. }
  48. static const struct regulator_ops isl_core_ops = {
  49. .get_voltage_sel = isl6271a_get_voltage_sel,
  50. .set_voltage_sel = isl6271a_set_voltage_sel,
  51. .list_voltage = regulator_list_voltage_linear,
  52. .map_voltage = regulator_map_voltage_linear,
  53. };
  54. static const struct regulator_ops isl_fixed_ops = {
  55. .list_voltage = regulator_list_voltage_linear,
  56. };
  57. static const struct regulator_desc isl_rd[] = {
  58. {
  59. .name = "Core Buck",
  60. .id = 0,
  61. .n_voltages = 16,
  62. .ops = &isl_core_ops,
  63. .type = REGULATOR_VOLTAGE,
  64. .owner = THIS_MODULE,
  65. .min_uV = ISL6271A_VOLTAGE_MIN,
  66. .uV_step = ISL6271A_VOLTAGE_STEP,
  67. }, {
  68. .name = "LDO1",
  69. .id = 1,
  70. .n_voltages = 1,
  71. .ops = &isl_fixed_ops,
  72. .type = REGULATOR_VOLTAGE,
  73. .owner = THIS_MODULE,
  74. .min_uV = 1100000,
  75. }, {
  76. .name = "LDO2",
  77. .id = 2,
  78. .n_voltages = 1,
  79. .ops = &isl_fixed_ops,
  80. .type = REGULATOR_VOLTAGE,
  81. .owner = THIS_MODULE,
  82. .min_uV = 1300000,
  83. },
  84. };
  85. static int isl6271a_probe(struct i2c_client *i2c,
  86. const struct i2c_device_id *id)
  87. {
  88. struct regulator_dev *rdev;
  89. struct regulator_config config = { };
  90. struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
  91. struct isl_pmic *pmic;
  92. int i;
  93. if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
  94. return -EIO;
  95. pmic = devm_kzalloc(&i2c->dev, sizeof(struct isl_pmic), GFP_KERNEL);
  96. if (!pmic)
  97. return -ENOMEM;
  98. pmic->client = i2c;
  99. mutex_init(&pmic->mtx);
  100. for (i = 0; i < 3; i++) {
  101. config.dev = &i2c->dev;
  102. if (i == 0)
  103. config.init_data = init_data;
  104. else
  105. config.init_data = NULL;
  106. config.driver_data = pmic;
  107. rdev = devm_regulator_register(&i2c->dev, &isl_rd[i], &config);
  108. if (IS_ERR(rdev)) {
  109. dev_err(&i2c->dev, "failed to register %s\n", id->name);
  110. return PTR_ERR(rdev);
  111. }
  112. }
  113. i2c_set_clientdata(i2c, pmic);
  114. return 0;
  115. }
  116. static const struct i2c_device_id isl6271a_id[] = {
  117. {.name = "isl6271a", 0 },
  118. { },
  119. };
  120. MODULE_DEVICE_TABLE(i2c, isl6271a_id);
  121. static struct i2c_driver isl6271a_i2c_driver = {
  122. .driver = {
  123. .name = "isl6271a",
  124. },
  125. .probe = isl6271a_probe,
  126. .id_table = isl6271a_id,
  127. };
  128. static int __init isl6271a_init(void)
  129. {
  130. return i2c_add_driver(&isl6271a_i2c_driver);
  131. }
  132. static void __exit isl6271a_cleanup(void)
  133. {
  134. i2c_del_driver(&isl6271a_i2c_driver);
  135. }
  136. subsys_initcall(isl6271a_init);
  137. module_exit(isl6271a_cleanup);
  138. MODULE_AUTHOR("Marek Vasut <[email protected]>");
  139. MODULE_DESCRIPTION("Intersil ISL6271A voltage regulator driver");
  140. MODULE_LICENSE("GPL v2");