^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * wm831x-irq.c -- Interrupt controller support for Wolfson WM831x PMICs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2009 Wolfson Microelectronics PLC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mfd/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mfd/wm831x/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mfd/wm831x/pdata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mfd/wm831x/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mfd/wm831x/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct wm831x_irq_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static struct wm831x_irq_data wm831x_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) [WM831X_IRQ_TEMP_THW] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .primary = WM831X_TEMP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .mask = WM831X_TEMP_THW_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) [WM831X_IRQ_GPIO_1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .mask = WM831X_GP1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) [WM831X_IRQ_GPIO_2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .mask = WM831X_GP2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) [WM831X_IRQ_GPIO_3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .mask = WM831X_GP3_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) [WM831X_IRQ_GPIO_4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .mask = WM831X_GP4_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) [WM831X_IRQ_GPIO_5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .mask = WM831X_GP5_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) [WM831X_IRQ_GPIO_6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .mask = WM831X_GP6_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) [WM831X_IRQ_GPIO_7] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .mask = WM831X_GP7_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) [WM831X_IRQ_GPIO_8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .mask = WM831X_GP8_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) [WM831X_IRQ_GPIO_9] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .mask = WM831X_GP9_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) [WM831X_IRQ_GPIO_10] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .mask = WM831X_GP10_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) [WM831X_IRQ_GPIO_11] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .mask = WM831X_GP11_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) [WM831X_IRQ_GPIO_12] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .mask = WM831X_GP12_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) [WM831X_IRQ_GPIO_13] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .mask = WM831X_GP13_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) [WM831X_IRQ_GPIO_14] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .mask = WM831X_GP14_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) [WM831X_IRQ_GPIO_15] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .mask = WM831X_GP15_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) [WM831X_IRQ_GPIO_16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .primary = WM831X_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .reg = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .mask = WM831X_GP16_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) [WM831X_IRQ_ON] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .primary = WM831X_ON_PIN_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .mask = WM831X_ON_PIN_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) [WM831X_IRQ_PPM_SYSLO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .primary = WM831X_PPM_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .mask = WM831X_PPM_SYSLO_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) [WM831X_IRQ_PPM_PWR_SRC] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .primary = WM831X_PPM_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .mask = WM831X_PPM_PWR_SRC_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) [WM831X_IRQ_PPM_USB_CURR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .primary = WM831X_PPM_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .mask = WM831X_PPM_USB_CURR_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) [WM831X_IRQ_WDOG_TO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .primary = WM831X_WDOG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .mask = WM831X_WDOG_TO_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) [WM831X_IRQ_RTC_PER] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .primary = WM831X_RTC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .mask = WM831X_RTC_PER_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) [WM831X_IRQ_RTC_ALM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .primary = WM831X_RTC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .mask = WM831X_RTC_ALM_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) [WM831X_IRQ_CHG_BATT_HOT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .primary = WM831X_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .reg = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .mask = WM831X_CHG_BATT_HOT_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) [WM831X_IRQ_CHG_BATT_COLD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .primary = WM831X_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .reg = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .mask = WM831X_CHG_BATT_COLD_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) [WM831X_IRQ_CHG_BATT_FAIL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .primary = WM831X_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .reg = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .mask = WM831X_CHG_BATT_FAIL_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) [WM831X_IRQ_CHG_OV] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .primary = WM831X_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .reg = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .mask = WM831X_CHG_OV_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) [WM831X_IRQ_CHG_END] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .primary = WM831X_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .reg = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .mask = WM831X_CHG_END_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) [WM831X_IRQ_CHG_TO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .primary = WM831X_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .reg = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .mask = WM831X_CHG_TO_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) [WM831X_IRQ_CHG_MODE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .primary = WM831X_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .reg = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .mask = WM831X_CHG_MODE_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) [WM831X_IRQ_CHG_START] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .primary = WM831X_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .reg = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .mask = WM831X_CHG_START_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) [WM831X_IRQ_TCHDATA] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .primary = WM831X_TCHDATA_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .mask = WM831X_TCHDATA_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) [WM831X_IRQ_TCHPD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .primary = WM831X_TCHPD_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .mask = WM831X_TCHPD_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) [WM831X_IRQ_AUXADC_DATA] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .primary = WM831X_AUXADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .mask = WM831X_AUXADC_DATA_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) [WM831X_IRQ_AUXADC_DCOMP1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .primary = WM831X_AUXADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .mask = WM831X_AUXADC_DCOMP1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) [WM831X_IRQ_AUXADC_DCOMP2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .primary = WM831X_AUXADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .mask = WM831X_AUXADC_DCOMP2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) [WM831X_IRQ_AUXADC_DCOMP3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .primary = WM831X_AUXADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .mask = WM831X_AUXADC_DCOMP3_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) [WM831X_IRQ_AUXADC_DCOMP4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .primary = WM831X_AUXADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .reg = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .mask = WM831X_AUXADC_DCOMP4_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) [WM831X_IRQ_CS1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .primary = WM831X_CS_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .reg = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .mask = WM831X_CS1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) [WM831X_IRQ_CS2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .primary = WM831X_CS_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .reg = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .mask = WM831X_CS2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) [WM831X_IRQ_HC_DC1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .primary = WM831X_HC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .reg = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .mask = WM831X_HC_DC1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) [WM831X_IRQ_HC_DC2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .primary = WM831X_HC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .reg = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .mask = WM831X_HC_DC2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) [WM831X_IRQ_UV_LDO1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .reg = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .mask = WM831X_UV_LDO1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) [WM831X_IRQ_UV_LDO2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .reg = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .mask = WM831X_UV_LDO2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) [WM831X_IRQ_UV_LDO3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .reg = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .mask = WM831X_UV_LDO3_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) [WM831X_IRQ_UV_LDO4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .reg = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .mask = WM831X_UV_LDO4_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) [WM831X_IRQ_UV_LDO5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .reg = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .mask = WM831X_UV_LDO5_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) [WM831X_IRQ_UV_LDO6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .reg = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .mask = WM831X_UV_LDO6_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) [WM831X_IRQ_UV_LDO7] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .reg = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .mask = WM831X_UV_LDO7_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) [WM831X_IRQ_UV_LDO8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .reg = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .mask = WM831X_UV_LDO8_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) [WM831X_IRQ_UV_LDO9] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .reg = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .mask = WM831X_UV_LDO9_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) [WM831X_IRQ_UV_LDO10] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .reg = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .mask = WM831X_UV_LDO10_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) [WM831X_IRQ_UV_DC1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .reg = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .mask = WM831X_UV_DC1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) [WM831X_IRQ_UV_DC2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) .reg = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .mask = WM831X_UV_DC2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) [WM831X_IRQ_UV_DC3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .reg = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .mask = WM831X_UV_DC3_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) [WM831X_IRQ_UV_DC4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .primary = WM831X_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .reg = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .mask = WM831X_UV_DC4_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return &wm831x_irqs[irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static void wm831x_irq_lock(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) mutex_lock(&wm831x->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static void wm831x_irq_sync_unlock(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) for (i = 0; i < ARRAY_SIZE(wm831x->gpio_update); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (wm831x->gpio_update[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) WM831X_GPN_INT_MODE | WM831X_GPN_POL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) wm831x->gpio_update[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) wm831x->gpio_update[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* If there's been a change in the mask write it back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * to the hardware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) dev_dbg(wm831x->dev, "IRQ mask sync: %x = %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) WM831X_INTERRUPT_STATUS_1_MASK + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) wm831x->irq_masks_cur[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) wm831x_reg_write(wm831x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) WM831X_INTERRUPT_STATUS_1_MASK + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) wm831x->irq_masks_cur[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) mutex_unlock(&wm831x->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static void wm831x_irq_enable(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) data->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static void wm831x_irq_disable(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) data->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static int wm831x_irq_set_type(struct irq_data *data, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) irq = data->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* Ignore internal-only IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (irq >= 0 && irq < WM831X_NUM_IRQS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* Rebase the IRQ into the GPIO range so we've got a sensible array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) irq -= WM831X_IRQ_GPIO_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* We set the high bit to flag that we need an update; don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * do the update here as we can be called with the bus lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) wm831x->gpio_level_low[irq] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) wm831x->gpio_level_high[irq] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) case IRQ_TYPE_EDGE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) wm831x->gpio_update[irq] = 0x10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) wm831x->gpio_level_high[irq] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) wm831x->gpio_update[irq] = 0x10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) wm831x->gpio_level_low[irq] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static struct irq_chip wm831x_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .name = "wm831x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .irq_bus_lock = wm831x_irq_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .irq_bus_sync_unlock = wm831x_irq_sync_unlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .irq_disable = wm831x_irq_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .irq_enable = wm831x_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .irq_set_type = wm831x_irq_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* The processing of the primary interrupt occurs in a thread so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * we can interact with the device over I2C or SPI. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static irqreturn_t wm831x_irq_thread(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct wm831x *wm831x = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int primary, status_addr, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int status_regs[WM831X_NUM_IRQ_REGS] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int read[WM831X_NUM_IRQ_REGS] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (primary < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dev_err(wm831x->dev, "Failed to read system interrupt: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /* The touch interrupts are visible in the primary register as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * an optimisation; open code this to avoid complicating the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * main handling loop and so we can also skip iterating the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * descriptors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (primary & WM831X_TCHPD_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) WM831X_IRQ_TCHPD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (primary & WM831X_TCHDATA_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) WM831X_IRQ_TCHDATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int offset = wm831x_irqs[i].reg - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (!(primary & wm831x_irqs[i].primary))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) status = &status_regs[offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Hopefully there should only be one register to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * each time otherwise we ought to do a block read. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (!read[offset]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) status_addr = irq_data_to_status_reg(&wm831x_irqs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) *status = wm831x_reg_read(wm831x, status_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (*status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) dev_err(wm831x->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) "Failed to read IRQ status: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) *status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) read[offset] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* Ignore any bits that we don't think are masked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) *status &= ~wm831x->irq_masks_cur[offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* Acknowledge now so we don't miss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * notifications while we handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) wm831x_reg_write(wm831x, status_addr, *status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (*status & wm831x_irqs[i].mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* Simulate an edge triggered IRQ by polling the input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * status. This is sucky but improves interoperability.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (primary == WM831X_GP_INT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) wm831x->gpio_level_high[i - WM831X_IRQ_GPIO_1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) ret = wm831x_reg_read(wm831x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) WM831X_GPIO_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (primary == WM831X_GP_INT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) wm831x->gpio_level_low[i - WM831X_IRQ_GPIO_1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) while (!(ret & 1 << (i - WM831X_IRQ_GPIO_1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ret = wm831x_reg_read(wm831x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) WM831X_GPIO_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static int wm831x_irq_map(struct irq_domain *h, unsigned int virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) irq_hw_number_t hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) irq_set_chip_data(virq, h->host_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) irq_set_chip_and_handler(virq, &wm831x_irq_chip, handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) irq_set_nested_thread(virq, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) irq_set_noprobe(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static const struct irq_domain_ops wm831x_irq_domain_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .map = wm831x_irq_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .xlate = irq_domain_xlate_twocell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int wm831x_irq_init(struct wm831x *wm831x, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct wm831x_pdata *pdata = &wm831x->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct irq_domain *domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int i, ret, irq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) mutex_init(&wm831x->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* Mask the individual interrupt sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) wm831x->irq_masks_cur[i] = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) wm831x->irq_masks_cache[i] = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /* Try to dynamically allocate IRQs if no base is specified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (pdata->irq_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) irq_base = irq_alloc_descs(pdata->irq_base, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) WM831X_NUM_IRQS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (irq_base < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) irq_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) irq_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) irq_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (irq_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) domain = irq_domain_add_legacy(wm831x->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ARRAY_SIZE(wm831x_irqs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) irq_base, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) &wm831x_irq_domain_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) wm831x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) domain = irq_domain_add_linear(wm831x->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ARRAY_SIZE(wm831x_irqs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) &wm831x_irq_domain_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) wm831x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (!domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) dev_warn(wm831x->dev, "Failed to allocate IRQ domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (pdata->irq_cmos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) i = WM831X_IRQ_OD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) WM831X_IRQ_OD, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) wm831x->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) wm831x->irq_domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* Try to flag /IRQ as a wake source; there are a number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * unconditional wake sources in the PMIC so this isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * conditional but we don't actually care *too* much if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ret = enable_irq_wake(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) dev_warn(wm831x->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) "Can't enable IRQ as wake source: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ret = request_threaded_irq(irq, NULL, wm831x_irq_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) IRQF_TRIGGER_LOW | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) "wm831x", wm831x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) dev_warn(wm831x->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) "No interrupt specified - functionality limited\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* Enable top level interrupts, we mask at secondary level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) void wm831x_irq_exit(struct wm831x *wm831x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (wm831x->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) free_irq(wm831x->irq, wm831x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }