intel_soc_pmic_chtdc_ti.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Device access for Dollar Cove TI PMIC
  3. *
  4. * Copyright (c) 2014, Intel Corporation.
  5. * Author: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
  6. *
  7. * Cleanup and forward-ported
  8. * Copyright (c) 2017 Takashi Iwai <tiwai@suse.de>
  9. *
  10. * This program 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. #include <linux/acpi.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/i2c.h>
  17. #include <linux/mfd/core.h>
  18. #include <linux/mfd/intel_soc_pmic.h>
  19. #include <linux/module.h>
  20. #include <linux/regmap.h>
  21. #define CHTDC_TI_IRQLVL1 0x01
  22. #define CHTDC_TI_MASK_IRQLVL1 0x02
  23. /* Level 1 IRQs */
  24. enum {
  25. CHTDC_TI_PWRBTN = 0, /* power button */
  26. CHTDC_TI_DIETMPWARN, /* thermal */
  27. CHTDC_TI_ADCCMPL, /* ADC */
  28. /* No IRQ 3 */
  29. CHTDC_TI_VBATLOW = 4, /* battery */
  30. CHTDC_TI_VBUSDET, /* power source */
  31. /* No IRQ 6 */
  32. CHTDC_TI_CCEOCAL = 7, /* battery */
  33. };
  34. static struct resource power_button_resources[] = {
  35. DEFINE_RES_IRQ(CHTDC_TI_PWRBTN),
  36. };
  37. static struct resource thermal_resources[] = {
  38. DEFINE_RES_IRQ(CHTDC_TI_DIETMPWARN),
  39. };
  40. static struct resource adc_resources[] = {
  41. DEFINE_RES_IRQ(CHTDC_TI_ADCCMPL),
  42. };
  43. static struct resource pwrsrc_resources[] = {
  44. DEFINE_RES_IRQ(CHTDC_TI_VBUSDET),
  45. };
  46. static struct resource battery_resources[] = {
  47. DEFINE_RES_IRQ(CHTDC_TI_VBATLOW),
  48. DEFINE_RES_IRQ(CHTDC_TI_CCEOCAL),
  49. };
  50. static struct mfd_cell chtdc_ti_dev[] = {
  51. {
  52. .name = "chtdc_ti_pwrbtn",
  53. .num_resources = ARRAY_SIZE(power_button_resources),
  54. .resources = power_button_resources,
  55. }, {
  56. .name = "chtdc_ti_adc",
  57. .num_resources = ARRAY_SIZE(adc_resources),
  58. .resources = adc_resources,
  59. }, {
  60. .name = "chtdc_ti_thermal",
  61. .num_resources = ARRAY_SIZE(thermal_resources),
  62. .resources = thermal_resources,
  63. }, {
  64. .name = "chtdc_ti_pwrsrc",
  65. .num_resources = ARRAY_SIZE(pwrsrc_resources),
  66. .resources = pwrsrc_resources,
  67. }, {
  68. .name = "chtdc_ti_battery",
  69. .num_resources = ARRAY_SIZE(battery_resources),
  70. .resources = battery_resources,
  71. },
  72. { .name = "chtdc_ti_region", },
  73. };
  74. static const struct regmap_config chtdc_ti_regmap_config = {
  75. .reg_bits = 8,
  76. .val_bits = 8,
  77. .max_register = 128,
  78. .cache_type = REGCACHE_NONE,
  79. };
  80. static const struct regmap_irq chtdc_ti_irqs[] = {
  81. REGMAP_IRQ_REG(CHTDC_TI_PWRBTN, 0, BIT(CHTDC_TI_PWRBTN)),
  82. REGMAP_IRQ_REG(CHTDC_TI_DIETMPWARN, 0, BIT(CHTDC_TI_DIETMPWARN)),
  83. REGMAP_IRQ_REG(CHTDC_TI_ADCCMPL, 0, BIT(CHTDC_TI_ADCCMPL)),
  84. REGMAP_IRQ_REG(CHTDC_TI_VBATLOW, 0, BIT(CHTDC_TI_VBATLOW)),
  85. REGMAP_IRQ_REG(CHTDC_TI_VBUSDET, 0, BIT(CHTDC_TI_VBUSDET)),
  86. REGMAP_IRQ_REG(CHTDC_TI_CCEOCAL, 0, BIT(CHTDC_TI_CCEOCAL)),
  87. };
  88. static const struct regmap_irq_chip chtdc_ti_irq_chip = {
  89. .name = KBUILD_MODNAME,
  90. .irqs = chtdc_ti_irqs,
  91. .num_irqs = ARRAY_SIZE(chtdc_ti_irqs),
  92. .num_regs = 1,
  93. .status_base = CHTDC_TI_IRQLVL1,
  94. .mask_base = CHTDC_TI_MASK_IRQLVL1,
  95. .ack_base = CHTDC_TI_IRQLVL1,
  96. };
  97. static int chtdc_ti_probe(struct i2c_client *i2c)
  98. {
  99. struct device *dev = &i2c->dev;
  100. struct intel_soc_pmic *pmic;
  101. int ret;
  102. pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
  103. if (!pmic)
  104. return -ENOMEM;
  105. i2c_set_clientdata(i2c, pmic);
  106. pmic->regmap = devm_regmap_init_i2c(i2c, &chtdc_ti_regmap_config);
  107. if (IS_ERR(pmic->regmap))
  108. return PTR_ERR(pmic->regmap);
  109. pmic->irq = i2c->irq;
  110. ret = devm_regmap_add_irq_chip(dev, pmic->regmap, pmic->irq,
  111. IRQF_ONESHOT, 0,
  112. &chtdc_ti_irq_chip,
  113. &pmic->irq_chip_data);
  114. if (ret)
  115. return ret;
  116. return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, chtdc_ti_dev,
  117. ARRAY_SIZE(chtdc_ti_dev), NULL, 0,
  118. regmap_irq_get_domain(pmic->irq_chip_data));
  119. }
  120. static void chtdc_ti_shutdown(struct i2c_client *i2c)
  121. {
  122. struct intel_soc_pmic *pmic = i2c_get_clientdata(i2c);
  123. disable_irq(pmic->irq);
  124. }
  125. static int __maybe_unused chtdc_ti_suspend(struct device *dev)
  126. {
  127. struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
  128. disable_irq(pmic->irq);
  129. return 0;
  130. }
  131. static int __maybe_unused chtdc_ti_resume(struct device *dev)
  132. {
  133. struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
  134. enable_irq(pmic->irq);
  135. return 0;
  136. }
  137. static SIMPLE_DEV_PM_OPS(chtdc_ti_pm_ops, chtdc_ti_suspend, chtdc_ti_resume);
  138. static const struct acpi_device_id chtdc_ti_acpi_ids[] = {
  139. { "INT33F5" },
  140. { },
  141. };
  142. MODULE_DEVICE_TABLE(acpi, chtdc_ti_acpi_ids);
  143. static struct i2c_driver chtdc_ti_i2c_driver = {
  144. .driver = {
  145. .name = "intel_soc_pmic_chtdc_ti",
  146. .pm = &chtdc_ti_pm_ops,
  147. .acpi_match_table = chtdc_ti_acpi_ids,
  148. },
  149. .probe_new = chtdc_ti_probe,
  150. .shutdown = chtdc_ti_shutdown,
  151. };
  152. module_i2c_driver(chtdc_ti_i2c_driver);
  153. MODULE_DESCRIPTION("I2C driver for Intel SoC Dollar Cove TI PMIC");
  154. MODULE_LICENSE("GPL v2");