1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2014 MediaTek Inc. 4 * Author: Flora Fu, MediaTek 5 */ 6 7 #include <linux/interrupt.h> 8 #include <linux/module.h> 9 #include <linux/of_device.h> 10 #include <linux/of_irq.h> 11 #include <linux/regmap.h> 12 #include <linux/mfd/core.h> 13 #include <linux/mfd/mt6397/core.h> 14 #include <linux/mfd/mt6323/core.h> 15 #include <linux/mfd/mt6397/registers.h> 16 #include <linux/mfd/mt6323/registers.h> 17 18 #define MT6397_RTC_BASE 0xe000 19 #define MT6397_RTC_SIZE 0x3e 20 21 #define MT6323_CID_CODE 0x23 22 #define MT6391_CID_CODE 0x91 23 #define MT6397_CID_CODE 0x97 24 25 static const struct resource mt6397_rtc_resources[] = { 26 { 27 .start = MT6397_RTC_BASE, 28 .end = MT6397_RTC_BASE + MT6397_RTC_SIZE, 29 .flags = IORESOURCE_MEM, 30 }, 31 { 32 .start = MT6397_IRQ_RTC, 33 .end = MT6397_IRQ_RTC, 34 .flags = IORESOURCE_IRQ, 35 }, 36 }; 37 38 static const struct resource mt6323_keys_resources[] = { 39 DEFINE_RES_IRQ(MT6323_IRQ_STATUS_PWRKEY), 40 DEFINE_RES_IRQ(MT6323_IRQ_STATUS_FCHRKEY), 41 }; 42 43 static const struct resource mt6397_keys_resources[] = { 44 DEFINE_RES_IRQ(MT6397_IRQ_PWRKEY), 45 DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY), 46 }; 47 48 static const struct mfd_cell mt6323_devs[] = { 49 { 50 .name = "mt6323-regulator", 51 .of_compatible = "mediatek,mt6323-regulator" 52 }, { 53 .name = "mt6323-led", 54 .of_compatible = "mediatek,mt6323-led" 55 }, { 56 .name = "mtk-pmic-keys", 57 .num_resources = ARRAY_SIZE(mt6323_keys_resources), 58 .resources = mt6323_keys_resources, 59 .of_compatible = "mediatek,mt6323-keys" 60 }, 61 }; 62 63 static const struct mfd_cell mt6397_devs[] = { 64 { 65 .name = "mt6397-rtc", 66 .num_resources = ARRAY_SIZE(mt6397_rtc_resources), 67 .resources = mt6397_rtc_resources, 68 .of_compatible = "mediatek,mt6397-rtc", 69 }, { 70 .name = "mt6397-regulator", 71 .of_compatible = "mediatek,mt6397-regulator", 72 }, { 73 .name = "mt6397-codec", 74 .of_compatible = "mediatek,mt6397-codec", 75 }, { 76 .name = "mt6397-clk", 77 .of_compatible = "mediatek,mt6397-clk", 78 }, { 79 .name = "mt6397-pinctrl", 80 .of_compatible = "mediatek,mt6397-pinctrl", 81 }, { 82 .name = "mtk-pmic-keys", 83 .num_resources = ARRAY_SIZE(mt6397_keys_resources), 84 .resources = mt6397_keys_resources, 85 .of_compatible = "mediatek,mt6397-keys" 86 } 87 }; 88 89 static void mt6397_irq_lock(struct irq_data *data) 90 { 91 struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); 92 93 mutex_lock(&mt6397->irqlock); 94 } 95 96 static void mt6397_irq_sync_unlock(struct irq_data *data) 97 { 98 struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); 99 100 regmap_write(mt6397->regmap, mt6397->int_con[0], 101 mt6397->irq_masks_cur[0]); 102 regmap_write(mt6397->regmap, mt6397->int_con[1], 103 mt6397->irq_masks_cur[1]); 104 105 mutex_unlock(&mt6397->irqlock); 106 } 107 108 static void mt6397_irq_disable(struct irq_data *data) 109 { 110 struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); 111 int shift = data->hwirq & 0xf; 112 int reg = data->hwirq >> 4; 113 114 mt6397->irq_masks_cur[reg] &= ~BIT(shift); 115 } 116 117 static void mt6397_irq_enable(struct irq_data *data) 118 { 119 struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); 120 int shift = data->hwirq & 0xf; 121 int reg = data->hwirq >> 4; 122 123 mt6397->irq_masks_cur[reg] |= BIT(shift); 124 } 125 126 #ifdef CONFIG_PM_SLEEP 127 static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on) 128 { 129 struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data); 130 int shift = irq_data->hwirq & 0xf; 131 int reg = irq_data->hwirq >> 4; 132 133 if (on) 134 mt6397->wake_mask[reg] |= BIT(shift); 135 else 136 mt6397->wake_mask[reg] &= ~BIT(shift); 137 138 return 0; 139 } 140 #else 141 #define mt6397_irq_set_wake NULL 142 #endif 143 144 static struct irq_chip mt6397_irq_chip = { 145 .name = "mt6397-irq", 146 .irq_bus_lock = mt6397_irq_lock, 147 .irq_bus_sync_unlock = mt6397_irq_sync_unlock, 148 .irq_enable = mt6397_irq_enable, 149 .irq_disable = mt6397_irq_disable, 150 .irq_set_wake = mt6397_irq_set_wake, 151 }; 152 153 static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg, 154 int irqbase) 155 { 156 unsigned int status; 157 int i, irq, ret; 158 159 ret = regmap_read(mt6397->regmap, reg, &status); 160 if (ret) { 161 dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret); 162 return; 163 } 164 165 for (i = 0; i < 16; i++) { 166 if (status & BIT(i)) { 167 irq = irq_find_mapping(mt6397->irq_domain, irqbase + i); 168 if (irq) 169 handle_nested_irq(irq); 170 } 171 } 172 173 regmap_write(mt6397->regmap, reg, status); 174 } 175 176 static irqreturn_t mt6397_irq_thread(int irq, void *data) 177 { 178 struct mt6397_chip *mt6397 = data; 179 180 mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0); 181 mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16); 182 183 return IRQ_HANDLED; 184 } 185 186 static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq, 187 irq_hw_number_t hw) 188 { 189 struct mt6397_chip *mt6397 = d->host_data; 190 191 irq_set_chip_data(irq, mt6397); 192 irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq); 193 irq_set_nested_thread(irq, 1); 194 irq_set_noprobe(irq); 195 196 return 0; 197 } 198 199 static const struct irq_domain_ops mt6397_irq_domain_ops = { 200 .map = mt6397_irq_domain_map, 201 }; 202 203 static int mt6397_irq_init(struct mt6397_chip *mt6397) 204 { 205 int ret; 206 207 mutex_init(&mt6397->irqlock); 208 209 /* Mask all interrupt sources */ 210 regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0); 211 regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0); 212 213 mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node, 214 MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397); 215 if (!mt6397->irq_domain) { 216 dev_err(mt6397->dev, "could not create irq domain\n"); 217 return -ENOMEM; 218 } 219 220 ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL, 221 mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397); 222 if (ret) { 223 dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n", 224 mt6397->irq, ret); 225 return ret; 226 } 227 228 return 0; 229 } 230 231 #ifdef CONFIG_PM_SLEEP 232 static int mt6397_irq_suspend(struct device *dev) 233 { 234 struct mt6397_chip *chip = dev_get_drvdata(dev); 235 236 regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]); 237 regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]); 238 239 enable_irq_wake(chip->irq); 240 241 return 0; 242 } 243 244 static int mt6397_irq_resume(struct device *dev) 245 { 246 struct mt6397_chip *chip = dev_get_drvdata(dev); 247 248 regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]); 249 regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]); 250 251 disable_irq_wake(chip->irq); 252 253 return 0; 254 } 255 #endif 256 257 static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend, 258 mt6397_irq_resume); 259 260 static int mt6397_probe(struct platform_device *pdev) 261 { 262 int ret; 263 unsigned int id; 264 struct mt6397_chip *pmic; 265 266 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); 267 if (!pmic) 268 return -ENOMEM; 269 270 pmic->dev = &pdev->dev; 271 272 /* 273 * mt6397 MFD is child device of soc pmic wrapper. 274 * Regmap is set from its parent. 275 */ 276 pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL); 277 if (!pmic->regmap) 278 return -ENODEV; 279 280 platform_set_drvdata(pdev, pmic); 281 282 ret = regmap_read(pmic->regmap, MT6397_CID, &id); 283 if (ret) { 284 dev_err(pmic->dev, "Failed to read chip id: %d\n", ret); 285 return ret; 286 } 287 288 pmic->irq = platform_get_irq(pdev, 0); 289 if (pmic->irq <= 0) 290 return pmic->irq; 291 292 switch (id & 0xff) { 293 case MT6323_CID_CODE: 294 pmic->int_con[0] = MT6323_INT_CON0; 295 pmic->int_con[1] = MT6323_INT_CON1; 296 pmic->int_status[0] = MT6323_INT_STATUS0; 297 pmic->int_status[1] = MT6323_INT_STATUS1; 298 ret = mt6397_irq_init(pmic); 299 if (ret) 300 return ret; 301 302 ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs, 303 ARRAY_SIZE(mt6323_devs), NULL, 304 0, pmic->irq_domain); 305 break; 306 307 case MT6397_CID_CODE: 308 case MT6391_CID_CODE: 309 pmic->int_con[0] = MT6397_INT_CON0; 310 pmic->int_con[1] = MT6397_INT_CON1; 311 pmic->int_status[0] = MT6397_INT_STATUS0; 312 pmic->int_status[1] = MT6397_INT_STATUS1; 313 ret = mt6397_irq_init(pmic); 314 if (ret) 315 return ret; 316 317 ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs, 318 ARRAY_SIZE(mt6397_devs), NULL, 319 0, pmic->irq_domain); 320 break; 321 322 default: 323 dev_err(&pdev->dev, "unsupported chip: %d\n", id); 324 return -ENODEV; 325 } 326 327 if (ret) { 328 irq_domain_remove(pmic->irq_domain); 329 dev_err(&pdev->dev, "failed to add child devices: %d\n", ret); 330 } 331 332 return ret; 333 } 334 335 static const struct of_device_id mt6397_of_match[] = { 336 { .compatible = "mediatek,mt6397" }, 337 { .compatible = "mediatek,mt6323" }, 338 { } 339 }; 340 MODULE_DEVICE_TABLE(of, mt6397_of_match); 341 342 static const struct platform_device_id mt6397_id[] = { 343 { "mt6397", 0 }, 344 { }, 345 }; 346 MODULE_DEVICE_TABLE(platform, mt6397_id); 347 348 static struct platform_driver mt6397_driver = { 349 .probe = mt6397_probe, 350 .driver = { 351 .name = "mt6397", 352 .of_match_table = of_match_ptr(mt6397_of_match), 353 .pm = &mt6397_pm_ops, 354 }, 355 .id_table = mt6397_id, 356 }; 357 358 module_platform_driver(mt6397_driver); 359 360 MODULE_AUTHOR("Flora Fu, MediaTek"); 361 MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC"); 362 MODULE_LICENSE("GPL"); 363