fan53555.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /*
  2. * FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver.
  3. *
  4. * Supported Part Numbers:
  5. * FAN53555UC00X/01X/03X/04X/05X
  6. *
  7. * Copyright (c) 2012 Marvell Technology Ltd.
  8. * Yunfan Zhang <yfzhang@marvell.com>
  9. *
  10. * This package is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. *
  14. */
  15. #include <linux/module.h>
  16. #include <linux/param.h>
  17. #include <linux/err.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/regulator/driver.h>
  20. #include <linux/regulator/machine.h>
  21. #include <linux/i2c.h>
  22. #include <linux/slab.h>
  23. #include <linux/regmap.h>
  24. #include <linux/regulator/fan53555.h>
  25. /* Voltage setting */
  26. #define FAN53555_VSEL0 0x00
  27. #define FAN53555_VSEL1 0x01
  28. /* Control register */
  29. #define FAN53555_CONTROL 0x02
  30. /* IC Type */
  31. #define FAN53555_ID1 0x03
  32. /* IC mask version */
  33. #define FAN53555_ID2 0x04
  34. /* Monitor register */
  35. #define FAN53555_MONITOR 0x05
  36. /* VSEL bit definitions */
  37. #define VSEL_BUCK_EN (1 << 7)
  38. #define VSEL_MODE (1 << 6)
  39. #define VSEL_NSEL_MASK 0x3F
  40. /* Chip ID and Verison */
  41. #define DIE_ID 0x0F /* ID1 */
  42. #define DIE_REV 0x0F /* ID2 */
  43. /* Control bit definitions */
  44. #define CTL_OUTPUT_DISCHG (1 << 7)
  45. #define CTL_SLEW_MASK (0x7 << 4)
  46. #define CTL_SLEW_SHIFT 4
  47. #define CTL_RESET (1 << 2)
  48. #define FAN53555_NVOLTAGES 64 /* Numbers of voltages */
  49. /* IC Type */
  50. enum {
  51. FAN53555_CHIP_ID_00 = 0,
  52. FAN53555_CHIP_ID_01,
  53. FAN53555_CHIP_ID_02,
  54. FAN53555_CHIP_ID_03,
  55. FAN53555_CHIP_ID_04,
  56. FAN53555_CHIP_ID_05,
  57. };
  58. struct fan53555_device_info {
  59. struct regmap *regmap;
  60. struct device *dev;
  61. struct regulator_desc desc;
  62. struct regulator_dev *rdev;
  63. struct regulator_init_data *regulator;
  64. /* IC Type and Rev */
  65. int chip_id;
  66. int chip_rev;
  67. /* Voltage setting register */
  68. unsigned int vol_reg;
  69. unsigned int sleep_reg;
  70. /* Voltage range and step(linear) */
  71. unsigned int vsel_min;
  72. unsigned int vsel_step;
  73. /* Voltage slew rate limiting */
  74. unsigned int slew_rate;
  75. /* Sleep voltage cache */
  76. unsigned int sleep_vol_cache;
  77. };
  78. static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
  79. {
  80. struct fan53555_device_info *di = rdev_get_drvdata(rdev);
  81. int ret;
  82. if (di->sleep_vol_cache == uV)
  83. return 0;
  84. ret = regulator_map_voltage_linear(rdev, uV, uV);
  85. if (ret < 0)
  86. return -EINVAL;
  87. ret = regmap_update_bits(di->regmap, di->sleep_reg,
  88. VSEL_NSEL_MASK, ret);
  89. if (ret < 0)
  90. return -EINVAL;
  91. /* Cache the sleep voltage setting.
  92. * Might not be the real voltage which is rounded */
  93. di->sleep_vol_cache = uV;
  94. return 0;
  95. }
  96. static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode)
  97. {
  98. struct fan53555_device_info *di = rdev_get_drvdata(rdev);
  99. switch (mode) {
  100. case REGULATOR_MODE_FAST:
  101. regmap_update_bits(di->regmap, di->vol_reg,
  102. VSEL_MODE, VSEL_MODE);
  103. break;
  104. case REGULATOR_MODE_NORMAL:
  105. regmap_update_bits(di->regmap, di->vol_reg, VSEL_MODE, 0);
  106. break;
  107. default:
  108. return -EINVAL;
  109. }
  110. return 0;
  111. }
  112. static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
  113. {
  114. struct fan53555_device_info *di = rdev_get_drvdata(rdev);
  115. unsigned int val;
  116. int ret = 0;
  117. ret = regmap_read(di->regmap, di->vol_reg, &val);
  118. if (ret < 0)
  119. return ret;
  120. if (val & VSEL_MODE)
  121. return REGULATOR_MODE_FAST;
  122. else
  123. return REGULATOR_MODE_NORMAL;
  124. }
  125. static struct regulator_ops fan53555_regulator_ops = {
  126. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  127. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  128. .map_voltage = regulator_map_voltage_linear,
  129. .list_voltage = regulator_list_voltage_linear,
  130. .set_suspend_voltage = fan53555_set_suspend_voltage,
  131. .enable = regulator_enable_regmap,
  132. .disable = regulator_disable_regmap,
  133. .is_enabled = regulator_is_enabled_regmap,
  134. .set_mode = fan53555_set_mode,
  135. .get_mode = fan53555_get_mode,
  136. };
  137. /* For 00,01,03,05 options:
  138. * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V.
  139. * For 04 option:
  140. * VOUT = 0.603V + NSELx * 12.826mV, from 0.603 to 1.411V.
  141. * */
  142. static int fan53555_device_setup(struct fan53555_device_info *di,
  143. struct fan53555_platform_data *pdata)
  144. {
  145. unsigned int reg, data, mask;
  146. /* Setup voltage control register */
  147. switch (pdata->sleep_vsel_id) {
  148. case FAN53555_VSEL_ID_0:
  149. di->sleep_reg = FAN53555_VSEL0;
  150. di->vol_reg = FAN53555_VSEL1;
  151. break;
  152. case FAN53555_VSEL_ID_1:
  153. di->sleep_reg = FAN53555_VSEL1;
  154. di->vol_reg = FAN53555_VSEL0;
  155. break;
  156. default:
  157. dev_err(di->dev, "Invalid VSEL ID!\n");
  158. return -EINVAL;
  159. }
  160. /* Init voltage range and step */
  161. switch (di->chip_id) {
  162. case FAN53555_CHIP_ID_00:
  163. case FAN53555_CHIP_ID_01:
  164. case FAN53555_CHIP_ID_03:
  165. case FAN53555_CHIP_ID_05:
  166. di->vsel_min = 600000;
  167. di->vsel_step = 10000;
  168. break;
  169. case FAN53555_CHIP_ID_04:
  170. di->vsel_min = 603000;
  171. di->vsel_step = 12826;
  172. break;
  173. default:
  174. dev_err(di->dev,
  175. "Chip ID[%d]\n not supported!\n", di->chip_id);
  176. return -EINVAL;
  177. }
  178. /* Init slew rate */
  179. if (pdata->slew_rate & 0x7)
  180. di->slew_rate = pdata->slew_rate;
  181. else
  182. di->slew_rate = FAN53555_SLEW_RATE_64MV;
  183. reg = FAN53555_CONTROL;
  184. data = di->slew_rate << CTL_SLEW_SHIFT;
  185. mask = CTL_SLEW_MASK;
  186. return regmap_update_bits(di->regmap, reg, mask, data);
  187. }
  188. static int fan53555_regulator_register(struct fan53555_device_info *di,
  189. struct regulator_config *config)
  190. {
  191. struct regulator_desc *rdesc = &di->desc;
  192. rdesc->name = "fan53555-reg";
  193. rdesc->ops = &fan53555_regulator_ops;
  194. rdesc->type = REGULATOR_VOLTAGE;
  195. rdesc->n_voltages = FAN53555_NVOLTAGES;
  196. rdesc->enable_reg = di->vol_reg;
  197. rdesc->enable_mask = VSEL_BUCK_EN;
  198. rdesc->min_uV = di->vsel_min;
  199. rdesc->uV_step = di->vsel_step;
  200. rdesc->vsel_reg = di->vol_reg;
  201. rdesc->vsel_mask = VSEL_NSEL_MASK;
  202. rdesc->owner = THIS_MODULE;
  203. di->rdev = regulator_register(&di->desc, config);
  204. if (IS_ERR(di->rdev))
  205. return PTR_ERR(di->rdev);
  206. return 0;
  207. }
  208. static struct regmap_config fan53555_regmap_config = {
  209. .reg_bits = 8,
  210. .val_bits = 8,
  211. };
  212. static int fan53555_regulator_probe(struct i2c_client *client,
  213. const struct i2c_device_id *id)
  214. {
  215. struct fan53555_device_info *di;
  216. struct fan53555_platform_data *pdata;
  217. struct regulator_config config = { };
  218. unsigned int val;
  219. int ret;
  220. pdata = client->dev.platform_data;
  221. if (!pdata || !pdata->regulator) {
  222. dev_err(&client->dev, "Platform data not found!\n");
  223. return -ENODEV;
  224. }
  225. di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info),
  226. GFP_KERNEL);
  227. if (!di) {
  228. dev_err(&client->dev, "Failed to allocate device info data!\n");
  229. return -ENOMEM;
  230. }
  231. di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
  232. if (IS_ERR(di->regmap)) {
  233. dev_err(&client->dev, "Failed to allocate regmap!\n");
  234. return PTR_ERR(di->regmap);
  235. }
  236. di->dev = &client->dev;
  237. di->regulator = pdata->regulator;
  238. i2c_set_clientdata(client, di);
  239. /* Get chip ID */
  240. ret = regmap_read(di->regmap, FAN53555_ID1, &val);
  241. if (ret < 0) {
  242. dev_err(&client->dev, "Failed to get chip ID!\n");
  243. return -ENODEV;
  244. }
  245. di->chip_id = val & DIE_ID;
  246. /* Get chip revision */
  247. ret = regmap_read(di->regmap, FAN53555_ID2, &val);
  248. if (ret < 0) {
  249. dev_err(&client->dev, "Failed to get chip Rev!\n");
  250. return -ENODEV;
  251. }
  252. di->chip_rev = val & DIE_REV;
  253. dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n",
  254. di->chip_id, di->chip_rev);
  255. /* Device init */
  256. ret = fan53555_device_setup(di, pdata);
  257. if (ret < 0) {
  258. dev_err(&client->dev, "Failed to setup device!\n");
  259. return ret;
  260. }
  261. /* Register regulator */
  262. config.dev = di->dev;
  263. config.init_data = di->regulator;
  264. config.regmap = di->regmap;
  265. config.driver_data = di;
  266. ret = fan53555_regulator_register(di, &config);
  267. if (ret < 0)
  268. dev_err(&client->dev, "Failed to register regulator!\n");
  269. return ret;
  270. }
  271. static int fan53555_regulator_remove(struct i2c_client *client)
  272. {
  273. struct fan53555_device_info *di = i2c_get_clientdata(client);
  274. regulator_unregister(di->rdev);
  275. return 0;
  276. }
  277. static const struct i2c_device_id fan53555_id[] = {
  278. {"fan53555", -1},
  279. { },
  280. };
  281. static struct i2c_driver fan53555_regulator_driver = {
  282. .driver = {
  283. .name = "fan53555-regulator",
  284. },
  285. .probe = fan53555_regulator_probe,
  286. .remove = fan53555_regulator_remove,
  287. .id_table = fan53555_id,
  288. };
  289. module_i2c_driver(fan53555_regulator_driver);
  290. MODULE_AUTHOR("Yunfan Zhang <yfzhang@marvell.com>");
  291. MODULE_DESCRIPTION("FAN53555 regulator driver");
  292. MODULE_LICENSE("GPL v2");