diff options
Diffstat (limited to 'drivers/mfd/max77693.c')
-rw-r--r-- | drivers/mfd/max77693.c | 158 |
1 files changed, 147 insertions, 11 deletions
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index a0308336adaf..249c139ef04a 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c | |||
@@ -55,12 +55,95 @@ static const struct regmap_config max77693_regmap_config = { | |||
55 | .max_register = MAX77693_PMIC_REG_END, | 55 | .max_register = MAX77693_PMIC_REG_END, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | static const struct regmap_irq max77693_led_irqs[] = { | ||
59 | { .mask = LED_IRQ_FLED2_OPEN, }, | ||
60 | { .mask = LED_IRQ_FLED2_SHORT, }, | ||
61 | { .mask = LED_IRQ_FLED1_OPEN, }, | ||
62 | { .mask = LED_IRQ_FLED1_SHORT, }, | ||
63 | { .mask = LED_IRQ_MAX_FLASH, }, | ||
64 | }; | ||
65 | |||
66 | static const struct regmap_irq_chip max77693_led_irq_chip = { | ||
67 | .name = "max77693-led", | ||
68 | .status_base = MAX77693_LED_REG_FLASH_INT, | ||
69 | .mask_base = MAX77693_LED_REG_FLASH_INT_MASK, | ||
70 | .mask_invert = false, | ||
71 | .num_regs = 1, | ||
72 | .irqs = max77693_led_irqs, | ||
73 | .num_irqs = ARRAY_SIZE(max77693_led_irqs), | ||
74 | }; | ||
75 | |||
76 | static const struct regmap_irq max77693_topsys_irqs[] = { | ||
77 | { .mask = TOPSYS_IRQ_T120C_INT, }, | ||
78 | { .mask = TOPSYS_IRQ_T140C_INT, }, | ||
79 | { .mask = TOPSYS_IRQ_LOWSYS_INT, }, | ||
80 | }; | ||
81 | |||
82 | static const struct regmap_irq_chip max77693_topsys_irq_chip = { | ||
83 | .name = "max77693-topsys", | ||
84 | .status_base = MAX77693_PMIC_REG_TOPSYS_INT, | ||
85 | .mask_base = MAX77693_PMIC_REG_TOPSYS_INT_MASK, | ||
86 | .mask_invert = false, | ||
87 | .num_regs = 1, | ||
88 | .irqs = max77693_topsys_irqs, | ||
89 | .num_irqs = ARRAY_SIZE(max77693_topsys_irqs), | ||
90 | }; | ||
91 | |||
92 | static const struct regmap_irq max77693_charger_irqs[] = { | ||
93 | { .mask = CHG_IRQ_BYP_I, }, | ||
94 | { .mask = CHG_IRQ_THM_I, }, | ||
95 | { .mask = CHG_IRQ_BAT_I, }, | ||
96 | { .mask = CHG_IRQ_CHG_I, }, | ||
97 | { .mask = CHG_IRQ_CHGIN_I, }, | ||
98 | }; | ||
99 | |||
100 | static const struct regmap_irq_chip max77693_charger_irq_chip = { | ||
101 | .name = "max77693-charger", | ||
102 | .status_base = MAX77693_CHG_REG_CHG_INT, | ||
103 | .mask_base = MAX77693_CHG_REG_CHG_INT_MASK, | ||
104 | .mask_invert = false, | ||
105 | .num_regs = 1, | ||
106 | .irqs = max77693_charger_irqs, | ||
107 | .num_irqs = ARRAY_SIZE(max77693_charger_irqs), | ||
108 | }; | ||
109 | |||
58 | static const struct regmap_config max77693_regmap_muic_config = { | 110 | static const struct regmap_config max77693_regmap_muic_config = { |
59 | .reg_bits = 8, | 111 | .reg_bits = 8, |
60 | .val_bits = 8, | 112 | .val_bits = 8, |
61 | .max_register = MAX77693_MUIC_REG_END, | 113 | .max_register = MAX77693_MUIC_REG_END, |
62 | }; | 114 | }; |
63 | 115 | ||
116 | static const struct regmap_irq max77693_muic_irqs[] = { | ||
117 | { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC, }, | ||
118 | { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_LOW, }, | ||
119 | { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_ERR, }, | ||
120 | { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC1K, }, | ||
121 | |||
122 | { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGTYP, }, | ||
123 | { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGDETREUN, }, | ||
124 | { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DCDTMR, }, | ||
125 | { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DXOVP, }, | ||
126 | { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VBVOLT, }, | ||
127 | { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VIDRM, }, | ||
128 | |||
129 | { .reg_offset = 2, .mask = MUIC_IRQ_INT3_EOC, }, | ||
130 | { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CGMBC, }, | ||
131 | { .reg_offset = 2, .mask = MUIC_IRQ_INT3_OVP, }, | ||
132 | { .reg_offset = 2, .mask = MUIC_IRQ_INT3_MBCCHG_ERR, }, | ||
133 | { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CHG_ENABLED, }, | ||
134 | { .reg_offset = 2, .mask = MUIC_IRQ_INT3_BAT_DET, }, | ||
135 | }; | ||
136 | |||
137 | static const struct regmap_irq_chip max77693_muic_irq_chip = { | ||
138 | .name = "max77693-muic", | ||
139 | .status_base = MAX77693_MUIC_REG_INT1, | ||
140 | .mask_base = MAX77693_MUIC_REG_INTMASK1, | ||
141 | .mask_invert = true, | ||
142 | .num_regs = 3, | ||
143 | .irqs = max77693_muic_irqs, | ||
144 | .num_irqs = ARRAY_SIZE(max77693_muic_irqs), | ||
145 | }; | ||
146 | |||
64 | static int max77693_i2c_probe(struct i2c_client *i2c, | 147 | static int max77693_i2c_probe(struct i2c_client *i2c, |
65 | const struct i2c_device_id *id) | 148 | const struct i2c_device_id *id) |
66 | { | 149 | { |
@@ -124,9 +207,45 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
124 | goto err_regmap_muic; | 207 | goto err_regmap_muic; |
125 | } | 208 | } |
126 | 209 | ||
127 | ret = max77693_irq_init(max77693); | 210 | ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, |
128 | if (ret < 0) | 211 | IRQF_ONESHOT | IRQF_SHARED | |
129 | goto err_irq; | 212 | IRQF_TRIGGER_FALLING, 0, |
213 | &max77693_led_irq_chip, | ||
214 | &max77693->irq_data_led); | ||
215 | if (ret) { | ||
216 | dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); | ||
217 | goto err_regmap_muic; | ||
218 | } | ||
219 | |||
220 | ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, | ||
221 | IRQF_ONESHOT | IRQF_SHARED | | ||
222 | IRQF_TRIGGER_FALLING, 0, | ||
223 | &max77693_topsys_irq_chip, | ||
224 | &max77693->irq_data_topsys); | ||
225 | if (ret) { | ||
226 | dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); | ||
227 | goto err_irq_topsys; | ||
228 | } | ||
229 | |||
230 | ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, | ||
231 | IRQF_ONESHOT | IRQF_SHARED | | ||
232 | IRQF_TRIGGER_FALLING, 0, | ||
233 | &max77693_charger_irq_chip, | ||
234 | &max77693->irq_data_charger); | ||
235 | if (ret) { | ||
236 | dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); | ||
237 | goto err_irq_charger; | ||
238 | } | ||
239 | |||
240 | ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, | ||
241 | IRQF_ONESHOT | IRQF_SHARED | | ||
242 | IRQF_TRIGGER_FALLING, 0, | ||
243 | &max77693_muic_irq_chip, | ||
244 | &max77693->irq_data_muic); | ||
245 | if (ret) { | ||
246 | dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); | ||
247 | goto err_irq_muic; | ||
248 | } | ||
130 | 249 | ||
131 | pm_runtime_set_active(max77693->dev); | 250 | pm_runtime_set_active(max77693->dev); |
132 | 251 | ||
@@ -138,8 +257,14 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
138 | return ret; | 257 | return ret; |
139 | 258 | ||
140 | err_mfd: | 259 | err_mfd: |
141 | max77693_irq_exit(max77693); | 260 | mfd_remove_devices(max77693->dev); |
142 | err_irq: | 261 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic); |
262 | err_irq_muic: | ||
263 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger); | ||
264 | err_irq_charger: | ||
265 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); | ||
266 | err_irq_topsys: | ||
267 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); | ||
143 | err_regmap_muic: | 268 | err_regmap_muic: |
144 | i2c_unregister_device(max77693->haptic); | 269 | i2c_unregister_device(max77693->haptic); |
145 | err_i2c_haptic: | 270 | err_i2c_haptic: |
@@ -152,7 +277,12 @@ static int max77693_i2c_remove(struct i2c_client *i2c) | |||
152 | struct max77693_dev *max77693 = i2c_get_clientdata(i2c); | 277 | struct max77693_dev *max77693 = i2c_get_clientdata(i2c); |
153 | 278 | ||
154 | mfd_remove_devices(max77693->dev); | 279 | mfd_remove_devices(max77693->dev); |
155 | max77693_irq_exit(max77693); | 280 | |
281 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic); | ||
282 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger); | ||
283 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); | ||
284 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); | ||
285 | |||
156 | i2c_unregister_device(max77693->muic); | 286 | i2c_unregister_device(max77693->muic); |
157 | i2c_unregister_device(max77693->haptic); | 287 | i2c_unregister_device(max77693->haptic); |
158 | 288 | ||
@@ -170,8 +300,11 @@ static int max77693_suspend(struct device *dev) | |||
170 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 300 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
171 | struct max77693_dev *max77693 = i2c_get_clientdata(i2c); | 301 | struct max77693_dev *max77693 = i2c_get_clientdata(i2c); |
172 | 302 | ||
173 | if (device_may_wakeup(dev)) | 303 | if (device_may_wakeup(dev)) { |
174 | irq_set_irq_wake(max77693->irq, 1); | 304 | enable_irq_wake(max77693->irq); |
305 | disable_irq(max77693->irq); | ||
306 | } | ||
307 | |||
175 | return 0; | 308 | return 0; |
176 | } | 309 | } |
177 | 310 | ||
@@ -180,9 +313,12 @@ static int max77693_resume(struct device *dev) | |||
180 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 313 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
181 | struct max77693_dev *max77693 = i2c_get_clientdata(i2c); | 314 | struct max77693_dev *max77693 = i2c_get_clientdata(i2c); |
182 | 315 | ||
183 | if (device_may_wakeup(dev)) | 316 | if (device_may_wakeup(dev)) { |
184 | irq_set_irq_wake(max77693->irq, 0); | 317 | disable_irq_wake(max77693->irq); |
185 | return max77693_irq_resume(max77693); | 318 | enable_irq(max77693->irq); |
319 | } | ||
320 | |||
321 | return 0; | ||
186 | } | 322 | } |
187 | 323 | ||
188 | static const struct dev_pm_ops max77693_pm = { | 324 | static const struct dev_pm_ops max77693_pm = { |