887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. From 63eeabbc9dbddd7381409feccd9082e5ffabfe59 Mon Sep 17 00:00:00 2001
  2. From: Aidan MacDonald <[email protected]>
  3. Date: Thu, 11 May 2023 10:26:08 +0100
  4. Subject: [PATCH] mfd: axp20x: Add support for AXP192
  5. The AXP192 PMIC is similar to the AXP202/AXP209, but with different
  6. regulators, additional GPIOs, and a different IRQ register layout.
  7. Signed-off-by: Aidan MacDonald <[email protected]>
  8. Link: https://lore.kernel.org/r/[email protected]
  9. Signed-off-by: Lee Jones <[email protected]>
  10. ---
  11. drivers/mfd/axp20x-i2c.c | 2 +
  12. drivers/mfd/axp20x.c | 141 +++++++++++++++++++++++++++++++++++++
  13. include/linux/mfd/axp20x.h | 84 ++++++++++++++++++++++
  14. 3 files changed, 227 insertions(+)
  15. --- a/drivers/mfd/axp20x-i2c.c
  16. +++ b/drivers/mfd/axp20x-i2c.c
  17. @@ -60,6 +60,7 @@ static void axp20x_i2c_remove(struct i2c
  18. #ifdef CONFIG_OF
  19. static const struct of_device_id axp20x_i2c_of_match[] = {
  20. { .compatible = "x-powers,axp152", .data = (void *)AXP152_ID },
  21. + { .compatible = "x-powers,axp192", .data = (void *)AXP192_ID },
  22. { .compatible = "x-powers,axp202", .data = (void *)AXP202_ID },
  23. { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
  24. { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
  25. @@ -75,6 +76,7 @@ MODULE_DEVICE_TABLE(of, axp20x_i2c_of_ma
  26. static const struct i2c_device_id axp20x_i2c_id[] = {
  27. { "axp152", 0 },
  28. + { "axp192", 0 },
  29. { "axp202", 0 },
  30. { "axp209", 0 },
  31. { "axp221", 0 },
  32. --- a/drivers/mfd/axp20x.c
  33. +++ b/drivers/mfd/axp20x.c
  34. @@ -34,6 +34,7 @@
  35. static const char * const axp20x_model_names[] = {
  36. "AXP152",
  37. + "AXP192",
  38. "AXP202",
  39. "AXP209",
  40. "AXP221",
  41. @@ -94,6 +95,35 @@ static const struct regmap_access_table
  42. .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges),
  43. };
  44. +static const struct regmap_range axp192_writeable_ranges[] = {
  45. + regmap_reg_range(AXP192_DATACACHE(0), AXP192_DATACACHE(5)),
  46. + regmap_reg_range(AXP192_PWR_OUT_CTRL, AXP192_IRQ5_STATE),
  47. + regmap_reg_range(AXP20X_DCDC_MODE, AXP192_N_RSTO_CTRL),
  48. + regmap_reg_range(AXP20X_CC_CTRL, AXP20X_CC_CTRL),
  49. +};
  50. +
  51. +static const struct regmap_range axp192_volatile_ranges[] = {
  52. + regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP192_USB_OTG_STATUS),
  53. + regmap_reg_range(AXP192_IRQ1_STATE, AXP192_IRQ4_STATE),
  54. + regmap_reg_range(AXP192_IRQ5_STATE, AXP192_IRQ5_STATE),
  55. + regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
  56. + regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
  57. + regmap_reg_range(AXP192_GPIO2_0_STATE, AXP192_GPIO2_0_STATE),
  58. + regmap_reg_range(AXP192_GPIO4_3_STATE, AXP192_GPIO4_3_STATE),
  59. + regmap_reg_range(AXP192_N_RSTO_CTRL, AXP192_N_RSTO_CTRL),
  60. + regmap_reg_range(AXP20X_CHRG_CC_31_24, AXP20X_CC_CTRL),
  61. +};
  62. +
  63. +static const struct regmap_access_table axp192_writeable_table = {
  64. + .yes_ranges = axp192_writeable_ranges,
  65. + .n_yes_ranges = ARRAY_SIZE(axp192_writeable_ranges),
  66. +};
  67. +
  68. +static const struct regmap_access_table axp192_volatile_table = {
  69. + .yes_ranges = axp192_volatile_ranges,
  70. + .n_yes_ranges = ARRAY_SIZE(axp192_volatile_ranges),
  71. +};
  72. +
  73. /* AXP22x ranges are shared with the AXP809, as they cover the same range */
  74. static const struct regmap_range axp22x_writeable_ranges[] = {
  75. regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
  76. @@ -220,6 +250,19 @@ static const struct resource axp152_pek_
  77. DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
  78. };
  79. +static const struct resource axp192_ac_power_supply_resources[] = {
  80. + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
  81. + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
  82. + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
  83. +};
  84. +
  85. +static const struct resource axp192_usb_power_supply_resources[] = {
  86. + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
  87. + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
  88. + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_VALID, "VBUS_VALID"),
  89. + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
  90. +};
  91. +
  92. static const struct resource axp20x_ac_power_supply_resources[] = {
  93. DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
  94. DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
  95. @@ -302,6 +345,15 @@ static const struct regmap_config axp152
  96. .cache_type = REGCACHE_RBTREE,
  97. };
  98. +static const struct regmap_config axp192_regmap_config = {
  99. + .reg_bits = 8,
  100. + .val_bits = 8,
  101. + .wr_table = &axp192_writeable_table,
  102. + .volatile_table = &axp192_volatile_table,
  103. + .max_register = AXP20X_CC_CTRL,
  104. + .cache_type = REGCACHE_RBTREE,
  105. +};
  106. +
  107. static const struct regmap_config axp20x_regmap_config = {
  108. .reg_bits = 8,
  109. .val_bits = 8,
  110. @@ -379,6 +431,42 @@ static const struct regmap_irq axp152_re
  111. INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0),
  112. };
  113. +static const struct regmap_irq axp192_regmap_irqs[] = {
  114. + INIT_REGMAP_IRQ(AXP192, ACIN_OVER_V, 0, 7),
  115. + INIT_REGMAP_IRQ(AXP192, ACIN_PLUGIN, 0, 6),
  116. + INIT_REGMAP_IRQ(AXP192, ACIN_REMOVAL, 0, 5),
  117. + INIT_REGMAP_IRQ(AXP192, VBUS_OVER_V, 0, 4),
  118. + INIT_REGMAP_IRQ(AXP192, VBUS_PLUGIN, 0, 3),
  119. + INIT_REGMAP_IRQ(AXP192, VBUS_REMOVAL, 0, 2),
  120. + INIT_REGMAP_IRQ(AXP192, VBUS_V_LOW, 0, 1),
  121. + INIT_REGMAP_IRQ(AXP192, BATT_PLUGIN, 1, 7),
  122. + INIT_REGMAP_IRQ(AXP192, BATT_REMOVAL, 1, 6),
  123. + INIT_REGMAP_IRQ(AXP192, BATT_ENT_ACT_MODE, 1, 5),
  124. + INIT_REGMAP_IRQ(AXP192, BATT_EXIT_ACT_MODE, 1, 4),
  125. + INIT_REGMAP_IRQ(AXP192, CHARG, 1, 3),
  126. + INIT_REGMAP_IRQ(AXP192, CHARG_DONE, 1, 2),
  127. + INIT_REGMAP_IRQ(AXP192, BATT_TEMP_HIGH, 1, 1),
  128. + INIT_REGMAP_IRQ(AXP192, BATT_TEMP_LOW, 1, 0),
  129. + INIT_REGMAP_IRQ(AXP192, DIE_TEMP_HIGH, 2, 7),
  130. + INIT_REGMAP_IRQ(AXP192, CHARG_I_LOW, 2, 6),
  131. + INIT_REGMAP_IRQ(AXP192, DCDC1_V_LONG, 2, 5),
  132. + INIT_REGMAP_IRQ(AXP192, DCDC2_V_LONG, 2, 4),
  133. + INIT_REGMAP_IRQ(AXP192, DCDC3_V_LONG, 2, 3),
  134. + INIT_REGMAP_IRQ(AXP192, PEK_SHORT, 2, 1),
  135. + INIT_REGMAP_IRQ(AXP192, PEK_LONG, 2, 0),
  136. + INIT_REGMAP_IRQ(AXP192, N_OE_PWR_ON, 3, 7),
  137. + INIT_REGMAP_IRQ(AXP192, N_OE_PWR_OFF, 3, 6),
  138. + INIT_REGMAP_IRQ(AXP192, VBUS_VALID, 3, 5),
  139. + INIT_REGMAP_IRQ(AXP192, VBUS_NOT_VALID, 3, 4),
  140. + INIT_REGMAP_IRQ(AXP192, VBUS_SESS_VALID, 3, 3),
  141. + INIT_REGMAP_IRQ(AXP192, VBUS_SESS_END, 3, 2),
  142. + INIT_REGMAP_IRQ(AXP192, LOW_PWR_LVL, 3, 0),
  143. + INIT_REGMAP_IRQ(AXP192, TIMER, 4, 7),
  144. + INIT_REGMAP_IRQ(AXP192, GPIO2_INPUT, 4, 2),
  145. + INIT_REGMAP_IRQ(AXP192, GPIO1_INPUT, 4, 1),
  146. + INIT_REGMAP_IRQ(AXP192, GPIO0_INPUT, 4, 0),
  147. +};
  148. +
  149. static const struct regmap_irq axp20x_regmap_irqs[] = {
  150. INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7),
  151. INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6),
  152. @@ -616,6 +704,32 @@ static const struct regmap_irq_chip axp1
  153. .num_regs = 3,
  154. };
  155. +static unsigned int axp192_get_irq_reg(struct regmap_irq_chip_data *data,
  156. + unsigned int base, int index)
  157. +{
  158. + /* linear mapping for IRQ1 to IRQ4 */
  159. + if (index < 4)
  160. + return base + index;
  161. +
  162. + /* handle IRQ5 separately */
  163. + if (base == AXP192_IRQ1_EN)
  164. + return AXP192_IRQ5_EN;
  165. +
  166. + return AXP192_IRQ5_STATE;
  167. +}
  168. +
  169. +static const struct regmap_irq_chip axp192_regmap_irq_chip = {
  170. + .name = "axp192_irq_chip",
  171. + .status_base = AXP192_IRQ1_STATE,
  172. + .ack_base = AXP192_IRQ1_STATE,
  173. + .unmask_base = AXP192_IRQ1_EN,
  174. + .init_ack_masked = true,
  175. + .irqs = axp192_regmap_irqs,
  176. + .num_irqs = ARRAY_SIZE(axp192_regmap_irqs),
  177. + .num_regs = 5,
  178. + .get_irq_reg = axp192_get_irq_reg,
  179. +};
  180. +
  181. static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
  182. .name = "axp20x_irq_chip",
  183. .status_base = AXP20X_IRQ1_STATE,
  184. @@ -712,6 +826,27 @@ static const struct regmap_irq_chip axp1
  185. .num_regs = 2,
  186. };
  187. +static const struct mfd_cell axp192_cells[] = {
  188. + {
  189. + .name = "axp192-adc",
  190. + .of_compatible = "x-powers,axp192-adc",
  191. + }, {
  192. + .name = "axp20x-battery-power-supply",
  193. + .of_compatible = "x-powers,axp192-battery-power-supply",
  194. + }, {
  195. + .name = "axp20x-ac-power-supply",
  196. + .of_compatible = "x-powers,axp202-ac-power-supply",
  197. + .num_resources = ARRAY_SIZE(axp192_ac_power_supply_resources),
  198. + .resources = axp192_ac_power_supply_resources,
  199. + }, {
  200. + .name = "axp20x-usb-power-supply",
  201. + .of_compatible = "x-powers,axp192-usb-power-supply",
  202. + .num_resources = ARRAY_SIZE(axp192_usb_power_supply_resources),
  203. + .resources = axp192_usb_power_supply_resources,
  204. + },
  205. + { .name = "axp20x-regulator" },
  206. +};
  207. +
  208. static const struct mfd_cell axp20x_cells[] = {
  209. {
  210. .name = "axp20x-gpio",
  211. @@ -1029,6 +1164,12 @@ int axp20x_match_device(struct axp20x_de
  212. axp20x->regmap_cfg = &axp152_regmap_config;
  213. axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
  214. break;
  215. + case AXP192_ID:
  216. + axp20x->nr_cells = ARRAY_SIZE(axp192_cells);
  217. + axp20x->cells = axp192_cells;
  218. + axp20x->regmap_cfg = &axp192_regmap_config;
  219. + axp20x->regmap_irq_chip = &axp192_regmap_irq_chip;
  220. + break;
  221. case AXP202_ID:
  222. case AXP209_ID:
  223. axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
  224. --- a/include/linux/mfd/axp20x.h
  225. +++ b/include/linux/mfd/axp20x.h
  226. @@ -12,6 +12,7 @@
  227. enum axp20x_variants {
  228. AXP152_ID = 0,
  229. + AXP192_ID,
  230. AXP202_ID,
  231. AXP209_ID,
  232. AXP221_ID,
  233. @@ -26,6 +27,7 @@ enum axp20x_variants {
  234. NR_AXP20X_VARIANTS,
  235. };
  236. +#define AXP192_DATACACHE(m) (0x06 + (m))
  237. #define AXP20X_DATACACHE(m) (0x04 + (m))
  238. /* Power supply */
  239. @@ -47,6 +49,13 @@ enum axp20x_variants {
  240. #define AXP152_DCDC_FREQ 0x37
  241. #define AXP152_DCDC_MODE 0x80
  242. +#define AXP192_USB_OTG_STATUS 0x04
  243. +#define AXP192_PWR_OUT_CTRL 0x12
  244. +#define AXP192_DCDC2_V_OUT 0x23
  245. +#define AXP192_DCDC1_V_OUT 0x26
  246. +#define AXP192_DCDC3_V_OUT 0x27
  247. +#define AXP192_LDO2_3_V_OUT 0x28
  248. +
  249. #define AXP20X_PWR_INPUT_STATUS 0x00
  250. #define AXP20X_PWR_OP_MODE 0x01
  251. #define AXP20X_USB_OTG_STATUS 0x02
  252. @@ -185,6 +194,17 @@ enum axp20x_variants {
  253. #define AXP152_IRQ2_STATE 0x49
  254. #define AXP152_IRQ3_STATE 0x4a
  255. +#define AXP192_IRQ1_EN 0x40
  256. +#define AXP192_IRQ2_EN 0x41
  257. +#define AXP192_IRQ3_EN 0x42
  258. +#define AXP192_IRQ4_EN 0x43
  259. +#define AXP192_IRQ1_STATE 0x44
  260. +#define AXP192_IRQ2_STATE 0x45
  261. +#define AXP192_IRQ3_STATE 0x46
  262. +#define AXP192_IRQ4_STATE 0x47
  263. +#define AXP192_IRQ5_EN 0x4a
  264. +#define AXP192_IRQ5_STATE 0x4d
  265. +
  266. #define AXP20X_IRQ1_EN 0x40
  267. #define AXP20X_IRQ2_EN 0x41
  268. #define AXP20X_IRQ3_EN 0x42
  269. @@ -204,6 +224,11 @@ enum axp20x_variants {
  270. #define AXP15060_IRQ2_STATE 0x49
  271. /* ADC */
  272. +#define AXP192_GPIO2_V_ADC_H 0x68
  273. +#define AXP192_GPIO2_V_ADC_L 0x69
  274. +#define AXP192_GPIO3_V_ADC_H 0x6a
  275. +#define AXP192_GPIO3_V_ADC_L 0x6b
  276. +
  277. #define AXP20X_ACIN_V_ADC_H 0x56
  278. #define AXP20X_ACIN_V_ADC_L 0x57
  279. #define AXP20X_ACIN_I_ADC_H 0x58
  280. @@ -233,6 +258,8 @@ enum axp20x_variants {
  281. #define AXP20X_IPSOUT_V_HIGH_L 0x7f
  282. /* Power supply */
  283. +#define AXP192_GPIO30_IN_RANGE 0x85
  284. +
  285. #define AXP20X_DCDC_MODE 0x80
  286. #define AXP20X_ADC_EN1 0x82
  287. #define AXP20X_ADC_EN2 0x83
  288. @@ -261,6 +288,16 @@ enum axp20x_variants {
  289. #define AXP152_PWM1_FREQ_Y 0x9c
  290. #define AXP152_PWM1_DUTY_CYCLE 0x9d
  291. +#define AXP192_GPIO0_CTRL 0x90
  292. +#define AXP192_LDO_IO0_V_OUT 0x91
  293. +#define AXP192_GPIO1_CTRL 0x92
  294. +#define AXP192_GPIO2_CTRL 0x93
  295. +#define AXP192_GPIO2_0_STATE 0x94
  296. +#define AXP192_GPIO4_3_CTRL 0x95
  297. +#define AXP192_GPIO4_3_STATE 0x96
  298. +#define AXP192_GPIO2_0_PULL 0x97
  299. +#define AXP192_N_RSTO_CTRL 0x9e
  300. +
  301. #define AXP20X_GPIO0_CTRL 0x90
  302. #define AXP20X_LDO5_V_OUT 0x91
  303. #define AXP20X_GPIO1_CTRL 0x92
  304. @@ -341,6 +378,17 @@ enum axp20x_variants {
  305. /* Regulators IDs */
  306. enum {
  307. + AXP192_DCDC1 = 0,
  308. + AXP192_DCDC2,
  309. + AXP192_DCDC3,
  310. + AXP192_LDO1,
  311. + AXP192_LDO2,
  312. + AXP192_LDO3,
  313. + AXP192_LDO_IO0,
  314. + AXP192_REG_ID_MAX
  315. +};
  316. +
  317. +enum {
  318. AXP20X_LDO1 = 0,
  319. AXP20X_LDO2,
  320. AXP20X_LDO3,
  321. @@ -531,6 +579,42 @@ enum {
  322. AXP152_IRQ_GPIO0_INPUT,
  323. };
  324. +enum axp192_irqs {
  325. + AXP192_IRQ_ACIN_OVER_V = 1,
  326. + AXP192_IRQ_ACIN_PLUGIN,
  327. + AXP192_IRQ_ACIN_REMOVAL,
  328. + AXP192_IRQ_VBUS_OVER_V,
  329. + AXP192_IRQ_VBUS_PLUGIN,
  330. + AXP192_IRQ_VBUS_REMOVAL,
  331. + AXP192_IRQ_VBUS_V_LOW,
  332. + AXP192_IRQ_BATT_PLUGIN,
  333. + AXP192_IRQ_BATT_REMOVAL,
  334. + AXP192_IRQ_BATT_ENT_ACT_MODE,
  335. + AXP192_IRQ_BATT_EXIT_ACT_MODE,
  336. + AXP192_IRQ_CHARG,
  337. + AXP192_IRQ_CHARG_DONE,
  338. + AXP192_IRQ_BATT_TEMP_HIGH,
  339. + AXP192_IRQ_BATT_TEMP_LOW,
  340. + AXP192_IRQ_DIE_TEMP_HIGH,
  341. + AXP192_IRQ_CHARG_I_LOW,
  342. + AXP192_IRQ_DCDC1_V_LONG,
  343. + AXP192_IRQ_DCDC2_V_LONG,
  344. + AXP192_IRQ_DCDC3_V_LONG,
  345. + AXP192_IRQ_PEK_SHORT = 22,
  346. + AXP192_IRQ_PEK_LONG,
  347. + AXP192_IRQ_N_OE_PWR_ON,
  348. + AXP192_IRQ_N_OE_PWR_OFF,
  349. + AXP192_IRQ_VBUS_VALID,
  350. + AXP192_IRQ_VBUS_NOT_VALID,
  351. + AXP192_IRQ_VBUS_SESS_VALID,
  352. + AXP192_IRQ_VBUS_SESS_END,
  353. + AXP192_IRQ_LOW_PWR_LVL = 31,
  354. + AXP192_IRQ_TIMER,
  355. + AXP192_IRQ_GPIO2_INPUT = 37,
  356. + AXP192_IRQ_GPIO1_INPUT,
  357. + AXP192_IRQ_GPIO0_INPUT,
  358. +};
  359. +
  360. enum {
  361. AXP20X_IRQ_ACIN_OVER_V = 1,
  362. AXP20X_IRQ_ACIN_PLUGIN,