100-mfd-axp20x-add-axp22x-pmic.patch 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. From f05be589ff32e87821b86845625ed3d402d37dc7 Mon Sep 17 00:00:00 2001
  2. From: Boris BREZILLON <boris.brezillon@free-electrons.com>
  3. Date: Fri, 10 Apr 2015 12:09:01 +0800
  4. Subject: [PATCH] mfd: axp20x: Add AXP22x PMIC support
  5. Add support for the AXP22x PMIC devices to the existing AXP20x driver.
  6. This includes the AXP221 and AXP223, which are identical except for
  7. the external data bus. Only AXP221 is added for now. AXP223 will be
  8. added after it's Reduced Serial Bus (RSB) interface is supported.
  9. AXP22x defines a new set of registers, power supplies and regulators,
  10. but most of the API is similar to the AXP20x ones.
  11. A new irq chip definition is used, even though the available interrupts
  12. on AXP22x is a subset of those on AXP20x. This is done so the interrupt
  13. numbers match those on the datasheet.
  14. This patch only enables the interrupts, system power-off function, and PEK
  15. sub-device. The regulator driver must first support different variants
  16. before we enable it from the mfd driver.
  17. Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
  18. [wens@csie.org: fix interrupts and move regulators to separate patch]
  19. Signed-off-by: Chen-Yu Tsai <wens@csie.org>
  20. Signed-off-by: Lee Jones <lee.jones@linaro.org>
  21. ---
  22. drivers/mfd/axp20x.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++
  23. include/linux/mfd/axp20x.h | 86 ++++++++++++++++++++++++++++++++++++++++
  24. 2 files changed, 184 insertions(+)
  25. --- a/drivers/mfd/axp20x.c
  26. +++ b/drivers/mfd/axp20x.c
  27. @@ -32,6 +32,7 @@
  28. static const char * const axp20x_model_names[] = {
  29. "AXP202",
  30. "AXP209",
  31. + "AXP221",
  32. "AXP288",
  33. };
  34. @@ -54,6 +55,25 @@ static const struct regmap_access_table
  35. .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges),
  36. };
  37. +static const struct regmap_range axp22x_writeable_ranges[] = {
  38. + regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
  39. + regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
  40. +};
  41. +
  42. +static const struct regmap_range axp22x_volatile_ranges[] = {
  43. + regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
  44. +};
  45. +
  46. +static const struct regmap_access_table axp22x_writeable_table = {
  47. + .yes_ranges = axp22x_writeable_ranges,
  48. + .n_yes_ranges = ARRAY_SIZE(axp22x_writeable_ranges),
  49. +};
  50. +
  51. +static const struct regmap_access_table axp22x_volatile_table = {
  52. + .yes_ranges = axp22x_volatile_ranges,
  53. + .n_yes_ranges = ARRAY_SIZE(axp22x_volatile_ranges),
  54. +};
  55. +
  56. static const struct regmap_range axp288_writeable_ranges[] = {
  57. regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
  58. regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
  59. @@ -87,6 +107,20 @@ static struct resource axp20x_pek_resour
  60. },
  61. };
  62. +static struct resource axp22x_pek_resources[] = {
  63. + {
  64. + .name = "PEK_DBR",
  65. + .start = AXP22X_IRQ_PEK_RIS_EDGE,
  66. + .end = AXP22X_IRQ_PEK_RIS_EDGE,
  67. + .flags = IORESOURCE_IRQ,
  68. + }, {
  69. + .name = "PEK_DBF",
  70. + .start = AXP22X_IRQ_PEK_FAL_EDGE,
  71. + .end = AXP22X_IRQ_PEK_FAL_EDGE,
  72. + .flags = IORESOURCE_IRQ,
  73. + },
  74. +};
  75. +
  76. static struct resource axp288_fuel_gauge_resources[] = {
  77. {
  78. .start = AXP288_IRQ_QWBTU,
  79. @@ -129,6 +163,15 @@ static const struct regmap_config axp20x
  80. .cache_type = REGCACHE_RBTREE,
  81. };
  82. +static const struct regmap_config axp22x_regmap_config = {
  83. + .reg_bits = 8,
  84. + .val_bits = 8,
  85. + .wr_table = &axp22x_writeable_table,
  86. + .volatile_table = &axp22x_volatile_table,
  87. + .max_register = AXP22X_BATLOW_THRES1,
  88. + .cache_type = REGCACHE_RBTREE,
  89. +};
  90. +
  91. static const struct regmap_config axp288_regmap_config = {
  92. .reg_bits = 8,
  93. .val_bits = 8,
  94. @@ -181,6 +224,34 @@ static const struct regmap_irq axp20x_re
  95. INIT_REGMAP_IRQ(AXP20X, GPIO0_INPUT, 4, 0),
  96. };
  97. +static const struct regmap_irq axp22x_regmap_irqs[] = {
  98. + INIT_REGMAP_IRQ(AXP22X, ACIN_OVER_V, 0, 7),
  99. + INIT_REGMAP_IRQ(AXP22X, ACIN_PLUGIN, 0, 6),
  100. + INIT_REGMAP_IRQ(AXP22X, ACIN_REMOVAL, 0, 5),
  101. + INIT_REGMAP_IRQ(AXP22X, VBUS_OVER_V, 0, 4),
  102. + INIT_REGMAP_IRQ(AXP22X, VBUS_PLUGIN, 0, 3),
  103. + INIT_REGMAP_IRQ(AXP22X, VBUS_REMOVAL, 0, 2),
  104. + INIT_REGMAP_IRQ(AXP22X, VBUS_V_LOW, 0, 1),
  105. + INIT_REGMAP_IRQ(AXP22X, BATT_PLUGIN, 1, 7),
  106. + INIT_REGMAP_IRQ(AXP22X, BATT_REMOVAL, 1, 6),
  107. + INIT_REGMAP_IRQ(AXP22X, BATT_ENT_ACT_MODE, 1, 5),
  108. + INIT_REGMAP_IRQ(AXP22X, BATT_EXIT_ACT_MODE, 1, 4),
  109. + INIT_REGMAP_IRQ(AXP22X, CHARG, 1, 3),
  110. + INIT_REGMAP_IRQ(AXP22X, CHARG_DONE, 1, 2),
  111. + INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_HIGH, 1, 1),
  112. + INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_LOW, 1, 0),
  113. + INIT_REGMAP_IRQ(AXP22X, DIE_TEMP_HIGH, 2, 7),
  114. + INIT_REGMAP_IRQ(AXP22X, PEK_SHORT, 2, 1),
  115. + INIT_REGMAP_IRQ(AXP22X, PEK_LONG, 2, 0),
  116. + INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL1, 3, 1),
  117. + INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL2, 3, 0),
  118. + INIT_REGMAP_IRQ(AXP22X, TIMER, 4, 7),
  119. + INIT_REGMAP_IRQ(AXP22X, PEK_RIS_EDGE, 4, 6),
  120. + INIT_REGMAP_IRQ(AXP22X, PEK_FAL_EDGE, 4, 5),
  121. + INIT_REGMAP_IRQ(AXP22X, GPIO1_INPUT, 4, 1),
  122. + INIT_REGMAP_IRQ(AXP22X, GPIO0_INPUT, 4, 0),
  123. +};
  124. +
  125. /* some IRQs are compatible with axp20x models */
  126. static const struct regmap_irq axp288_regmap_irqs[] = {
  127. INIT_REGMAP_IRQ(AXP288, VBUS_FALL, 0, 2),
  128. @@ -224,6 +295,7 @@ static const struct regmap_irq axp288_re
  129. static const struct of_device_id axp20x_of_match[] = {
  130. { .compatible = "x-powers,axp202", .data = (void *) AXP202_ID },
  131. { .compatible = "x-powers,axp209", .data = (void *) AXP209_ID },
  132. + { .compatible = "x-powers,axp221", .data = (void *) AXP221_ID },
  133. { },
  134. };
  135. MODULE_DEVICE_TABLE(of, axp20x_of_match);
  136. @@ -258,6 +330,18 @@ static const struct regmap_irq_chip axp2
  137. };
  138. +static const struct regmap_irq_chip axp22x_regmap_irq_chip = {
  139. + .name = "axp22x_irq_chip",
  140. + .status_base = AXP20X_IRQ1_STATE,
  141. + .ack_base = AXP20X_IRQ1_STATE,
  142. + .mask_base = AXP20X_IRQ1_EN,
  143. + .mask_invert = true,
  144. + .init_ack_masked = true,
  145. + .irqs = axp22x_regmap_irqs,
  146. + .num_irqs = ARRAY_SIZE(axp22x_regmap_irqs),
  147. + .num_regs = 5,
  148. +};
  149. +
  150. static const struct regmap_irq_chip axp288_regmap_irq_chip = {
  151. .name = "axp288_irq_chip",
  152. .status_base = AXP20X_IRQ1_STATE,
  153. @@ -281,6 +365,14 @@ static struct mfd_cell axp20x_cells[] =
  154. },
  155. };
  156. +static struct mfd_cell axp22x_cells[] = {
  157. + {
  158. + .name = "axp20x-pek",
  159. + .num_resources = ARRAY_SIZE(axp22x_pek_resources),
  160. + .resources = axp22x_pek_resources,
  161. + },
  162. +};
  163. +
  164. static struct resource axp288_adc_resources[] = {
  165. {
  166. .name = "GPADC",
  167. @@ -426,6 +518,12 @@ static int axp20x_match_device(struct ax
  168. axp20x->regmap_cfg = &axp20x_regmap_config;
  169. axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
  170. break;
  171. + case AXP221_ID:
  172. + axp20x->nr_cells = ARRAY_SIZE(axp22x_cells);
  173. + axp20x->cells = axp22x_cells;
  174. + axp20x->regmap_cfg = &axp22x_regmap_config;
  175. + axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
  176. + break;
  177. case AXP288_ID:
  178. axp20x->cells = axp288_cells;
  179. axp20x->nr_cells = ARRAY_SIZE(axp288_cells);
  180. --- a/include/linux/mfd/axp20x.h
  181. +++ b/include/linux/mfd/axp20x.h
  182. @@ -14,6 +14,7 @@
  183. enum {
  184. AXP202_ID = 0,
  185. AXP209_ID,
  186. + AXP221_ID,
  187. AXP288_ID,
  188. NR_AXP20X_VARIANTS,
  189. };
  190. @@ -45,6 +46,28 @@ enum {
  191. #define AXP20X_V_LTF_DISCHRG 0x3c
  192. #define AXP20X_V_HTF_DISCHRG 0x3d
  193. +#define AXP22X_PWR_OUT_CTRL1 0x10
  194. +#define AXP22X_PWR_OUT_CTRL2 0x12
  195. +#define AXP22X_PWR_OUT_CTRL3 0x13
  196. +#define AXP22X_DLDO1_V_OUT 0x15
  197. +#define AXP22X_DLDO2_V_OUT 0x16
  198. +#define AXP22X_DLDO3_V_OUT 0x17
  199. +#define AXP22X_DLDO4_V_OUT 0x18
  200. +#define AXP22X_ELDO1_V_OUT 0x19
  201. +#define AXP22X_ELDO2_V_OUT 0x1a
  202. +#define AXP22X_ELDO3_V_OUT 0x1b
  203. +#define AXP22X_DC5LDO_V_OUT 0x1c
  204. +#define AXP22X_DCDC1_V_OUT 0x21
  205. +#define AXP22X_DCDC2_V_OUT 0x22
  206. +#define AXP22X_DCDC3_V_OUT 0x23
  207. +#define AXP22X_DCDC4_V_OUT 0x24
  208. +#define AXP22X_DCDC5_V_OUT 0x25
  209. +#define AXP22X_DCDC23_V_RAMP_CTRL 0x27
  210. +#define AXP22X_ALDO1_V_OUT 0x28
  211. +#define AXP22X_ALDO2_V_OUT 0x29
  212. +#define AXP22X_ALDO3_V_OUT 0x2a
  213. +#define AXP22X_CHRG_CTRL3 0x35
  214. +
  215. /* Interrupt */
  216. #define AXP20X_IRQ1_EN 0x40
  217. #define AXP20X_IRQ2_EN 0x41
  218. @@ -100,6 +123,9 @@ enum {
  219. #define AXP20X_VBUS_MON 0x8b
  220. #define AXP20X_OVER_TMP 0x8f
  221. +#define AXP22X_PWREN_CTRL1 0x8c
  222. +#define AXP22X_PWREN_CTRL2 0x8d
  223. +
  224. /* GPIO */
  225. #define AXP20X_GPIO0_CTRL 0x90
  226. #define AXP20X_LDO5_V_OUT 0x91
  227. @@ -108,6 +134,11 @@ enum {
  228. #define AXP20X_GPIO20_SS 0x94
  229. #define AXP20X_GPIO3_CTRL 0x95
  230. +#define AXP22X_LDO_IO0_V_OUT 0x91
  231. +#define AXP22X_LDO_IO1_V_OUT 0x93
  232. +#define AXP22X_GPIO_STATE 0x94
  233. +#define AXP22X_GPIO_PULL_DOWN 0x95
  234. +
  235. /* Battery */
  236. #define AXP20X_CHRG_CC_31_24 0xb0
  237. #define AXP20X_CHRG_CC_23_16 0xb1
  238. @@ -120,6 +151,9 @@ enum {
  239. #define AXP20X_CC_CTRL 0xb8
  240. #define AXP20X_FG_RES 0xb9
  241. +/* AXP22X specific registers */
  242. +#define AXP22X_BATLOW_THRES1 0xe6
  243. +
  244. /* AXP288 specific registers */
  245. #define AXP288_PMIC_ADC_H 0x56
  246. #define AXP288_PMIC_ADC_L 0x57
  247. @@ -158,6 +192,30 @@ enum {
  248. AXP20X_REG_ID_MAX,
  249. };
  250. +enum {
  251. + AXP22X_DCDC1 = 0,
  252. + AXP22X_DCDC2,
  253. + AXP22X_DCDC3,
  254. + AXP22X_DCDC4,
  255. + AXP22X_DCDC5,
  256. + AXP22X_DC1SW,
  257. + AXP22X_DC5LDO,
  258. + AXP22X_ALDO1,
  259. + AXP22X_ALDO2,
  260. + AXP22X_ALDO3,
  261. + AXP22X_ELDO1,
  262. + AXP22X_ELDO2,
  263. + AXP22X_ELDO3,
  264. + AXP22X_DLDO1,
  265. + AXP22X_DLDO2,
  266. + AXP22X_DLDO3,
  267. + AXP22X_DLDO4,
  268. + AXP22X_RTC_LDO,
  269. + AXP22X_LDO_IO0,
  270. + AXP22X_LDO_IO1,
  271. + AXP22X_REG_ID_MAX,
  272. +};
  273. +
  274. /* IRQs */
  275. enum {
  276. AXP20X_IRQ_ACIN_OVER_V = 1,
  277. @@ -199,6 +257,34 @@ enum {
  278. AXP20X_IRQ_GPIO0_INPUT,
  279. };
  280. +enum axp22x_irqs {
  281. + AXP22X_IRQ_ACIN_OVER_V = 1,
  282. + AXP22X_IRQ_ACIN_PLUGIN,
  283. + AXP22X_IRQ_ACIN_REMOVAL,
  284. + AXP22X_IRQ_VBUS_OVER_V,
  285. + AXP22X_IRQ_VBUS_PLUGIN,
  286. + AXP22X_IRQ_VBUS_REMOVAL,
  287. + AXP22X_IRQ_VBUS_V_LOW,
  288. + AXP22X_IRQ_BATT_PLUGIN,
  289. + AXP22X_IRQ_BATT_REMOVAL,
  290. + AXP22X_IRQ_BATT_ENT_ACT_MODE,
  291. + AXP22X_IRQ_BATT_EXIT_ACT_MODE,
  292. + AXP22X_IRQ_CHARG,
  293. + AXP22X_IRQ_CHARG_DONE,
  294. + AXP22X_IRQ_BATT_TEMP_HIGH,
  295. + AXP22X_IRQ_BATT_TEMP_LOW,
  296. + AXP22X_IRQ_DIE_TEMP_HIGH,
  297. + AXP22X_IRQ_PEK_SHORT,
  298. + AXP22X_IRQ_PEK_LONG,
  299. + AXP22X_IRQ_LOW_PWR_LVL1,
  300. + AXP22X_IRQ_LOW_PWR_LVL2,
  301. + AXP22X_IRQ_TIMER,
  302. + AXP22X_IRQ_PEK_RIS_EDGE,
  303. + AXP22X_IRQ_PEK_FAL_EDGE,
  304. + AXP22X_IRQ_GPIO1_INPUT,
  305. + AXP22X_IRQ_GPIO0_INPUT,
  306. +};
  307. +
  308. enum axp288_irqs {
  309. AXP288_IRQ_VBUS_FALL = 2,
  310. AXP288_IRQ_VBUS_RISE,