^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) * wm8350-irq.c -- IRQ support for Wolfson WM8350
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2007, 2008, 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: Liam Girdwood, Mark Brown
^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/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mfd/wm8350/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mfd/wm8350/audio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mfd/wm8350/comparator.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mfd/wm8350/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mfd/wm8350/pmic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mfd/wm8350/rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/mfd/wm8350/supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/mfd/wm8350/wdt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define WM8350_INT_OFFSET_1 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define WM8350_INT_OFFSET_2 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define WM8350_POWER_UP_INT_OFFSET 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define WM8350_UNDER_VOLTAGE_INT_OFFSET 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define WM8350_OVER_CURRENT_INT_OFFSET 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define WM8350_GPIO_INT_OFFSET 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define WM8350_COMPARATOR_INT_OFFSET 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct wm8350_irq_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int primary_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static struct wm8350_irq_data wm8350_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) [WM8350_IRQ_OC_LS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .primary = WM8350_OC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .reg = WM8350_OVER_CURRENT_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .mask = WM8350_OC_LS_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .primary_only = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) [WM8350_IRQ_UV_DC1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .primary = WM8350_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .mask = WM8350_UV_DC1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) [WM8350_IRQ_UV_DC2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .primary = WM8350_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .mask = WM8350_UV_DC2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) [WM8350_IRQ_UV_DC3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .primary = WM8350_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .mask = WM8350_UV_DC3_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) [WM8350_IRQ_UV_DC4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .primary = WM8350_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .mask = WM8350_UV_DC4_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) [WM8350_IRQ_UV_DC5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .primary = WM8350_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .mask = WM8350_UV_DC5_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) [WM8350_IRQ_UV_DC6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .primary = WM8350_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .mask = WM8350_UV_DC6_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) [WM8350_IRQ_UV_LDO1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .primary = WM8350_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .mask = WM8350_UV_LDO1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) [WM8350_IRQ_UV_LDO2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .primary = WM8350_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .mask = WM8350_UV_LDO2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) [WM8350_IRQ_UV_LDO3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .primary = WM8350_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .mask = WM8350_UV_LDO3_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) [WM8350_IRQ_UV_LDO4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .primary = WM8350_UV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .mask = WM8350_UV_LDO4_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) [WM8350_IRQ_CHG_BAT_HOT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .primary = WM8350_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .mask = WM8350_CHG_BAT_HOT_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) [WM8350_IRQ_CHG_BAT_COLD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .primary = WM8350_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .mask = WM8350_CHG_BAT_COLD_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) [WM8350_IRQ_CHG_BAT_FAIL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .primary = WM8350_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .mask = WM8350_CHG_BAT_FAIL_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) [WM8350_IRQ_CHG_TO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .primary = WM8350_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .mask = WM8350_CHG_TO_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) [WM8350_IRQ_CHG_END] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .primary = WM8350_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .mask = WM8350_CHG_END_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) [WM8350_IRQ_CHG_START] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .primary = WM8350_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .mask = WM8350_CHG_START_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) [WM8350_IRQ_CHG_FAST_RDY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .primary = WM8350_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .mask = WM8350_CHG_FAST_RDY_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) [WM8350_IRQ_CHG_VBATT_LT_3P9] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .primary = WM8350_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .mask = WM8350_CHG_VBATT_LT_3P9_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) [WM8350_IRQ_CHG_VBATT_LT_3P1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .primary = WM8350_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .mask = WM8350_CHG_VBATT_LT_3P1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) [WM8350_IRQ_CHG_VBATT_LT_2P85] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .primary = WM8350_CHG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .mask = WM8350_CHG_VBATT_LT_2P85_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) [WM8350_IRQ_RTC_ALM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .primary = WM8350_RTC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .mask = WM8350_RTC_ALM_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) [WM8350_IRQ_RTC_SEC] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .primary = WM8350_RTC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .mask = WM8350_RTC_SEC_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) [WM8350_IRQ_RTC_PER] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .primary = WM8350_RTC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .reg = WM8350_INT_OFFSET_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .mask = WM8350_RTC_PER_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) [WM8350_IRQ_CS1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .primary = WM8350_CS_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .mask = WM8350_CS1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) [WM8350_IRQ_CS2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .primary = WM8350_CS_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .mask = WM8350_CS2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) [WM8350_IRQ_SYS_HYST_COMP_FAIL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .primary = WM8350_SYS_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .mask = WM8350_SYS_HYST_COMP_FAIL_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) [WM8350_IRQ_SYS_CHIP_GT115] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .primary = WM8350_SYS_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .mask = WM8350_SYS_CHIP_GT115_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) [WM8350_IRQ_SYS_CHIP_GT140] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .primary = WM8350_SYS_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .mask = WM8350_SYS_CHIP_GT140_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) [WM8350_IRQ_SYS_WDOG_TO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .primary = WM8350_SYS_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .mask = WM8350_SYS_WDOG_TO_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) [WM8350_IRQ_AUXADC_DATARDY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .primary = WM8350_AUXADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .mask = WM8350_AUXADC_DATARDY_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) [WM8350_IRQ_AUXADC_DCOMP4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .primary = WM8350_AUXADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .mask = WM8350_AUXADC_DCOMP4_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) [WM8350_IRQ_AUXADC_DCOMP3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .primary = WM8350_AUXADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .mask = WM8350_AUXADC_DCOMP3_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) [WM8350_IRQ_AUXADC_DCOMP2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .primary = WM8350_AUXADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .mask = WM8350_AUXADC_DCOMP2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) [WM8350_IRQ_AUXADC_DCOMP1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .primary = WM8350_AUXADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .mask = WM8350_AUXADC_DCOMP1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) [WM8350_IRQ_USB_LIMIT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .primary = WM8350_USB_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .reg = WM8350_INT_OFFSET_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .mask = WM8350_USB_LIMIT_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .primary_only = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) [WM8350_IRQ_WKUP_OFF_STATE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .primary = WM8350_WKUP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .mask = WM8350_WKUP_OFF_STATE_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) [WM8350_IRQ_WKUP_HIB_STATE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .primary = WM8350_WKUP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .mask = WM8350_WKUP_HIB_STATE_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) [WM8350_IRQ_WKUP_CONV_FAULT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .primary = WM8350_WKUP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .mask = WM8350_WKUP_CONV_FAULT_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) [WM8350_IRQ_WKUP_WDOG_RST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .primary = WM8350_WKUP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) .mask = WM8350_WKUP_WDOG_RST_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) [WM8350_IRQ_WKUP_GP_PWR_ON] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .primary = WM8350_WKUP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .mask = WM8350_WKUP_GP_PWR_ON_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) [WM8350_IRQ_WKUP_ONKEY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .primary = WM8350_WKUP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .mask = WM8350_WKUP_ONKEY_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) [WM8350_IRQ_WKUP_GP_WAKEUP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .primary = WM8350_WKUP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .mask = WM8350_WKUP_GP_WAKEUP_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) [WM8350_IRQ_CODEC_JCK_DET_L] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .primary = WM8350_CODEC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .mask = WM8350_CODEC_JCK_DET_L_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) [WM8350_IRQ_CODEC_JCK_DET_R] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .primary = WM8350_CODEC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .mask = WM8350_CODEC_JCK_DET_R_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) [WM8350_IRQ_CODEC_MICSCD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .primary = WM8350_CODEC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .mask = WM8350_CODEC_MICSCD_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) [WM8350_IRQ_CODEC_MICD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .primary = WM8350_CODEC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .mask = WM8350_CODEC_MICD_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) [WM8350_IRQ_EXT_USB_FB] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .primary = WM8350_EXT_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) .mask = WM8350_EXT_USB_FB_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) [WM8350_IRQ_EXT_WALL_FB] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .primary = WM8350_EXT_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) .mask = WM8350_EXT_WALL_FB_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) [WM8350_IRQ_EXT_BAT_FB] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .primary = WM8350_EXT_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .reg = WM8350_COMPARATOR_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .mask = WM8350_EXT_BAT_FB_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) [WM8350_IRQ_GPIO(0)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .mask = WM8350_GP0_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) [WM8350_IRQ_GPIO(1)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .mask = WM8350_GP1_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) [WM8350_IRQ_GPIO(2)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .mask = WM8350_GP2_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) [WM8350_IRQ_GPIO(3)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .mask = WM8350_GP3_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) [WM8350_IRQ_GPIO(4)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .mask = WM8350_GP4_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) [WM8350_IRQ_GPIO(5)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .mask = WM8350_GP5_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) [WM8350_IRQ_GPIO(6)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .mask = WM8350_GP6_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) [WM8350_IRQ_GPIO(7)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) .mask = WM8350_GP7_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) [WM8350_IRQ_GPIO(8)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .mask = WM8350_GP8_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) [WM8350_IRQ_GPIO(9)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .mask = WM8350_GP9_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) [WM8350_IRQ_GPIO(10)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .mask = WM8350_GP10_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) [WM8350_IRQ_GPIO(11)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .mask = WM8350_GP11_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) [WM8350_IRQ_GPIO(12)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .primary = WM8350_GP_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .reg = WM8350_GPIO_INT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .mask = WM8350_GP12_EINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static inline struct wm8350_irq_data *irq_to_wm8350_irq(struct wm8350 *wm8350,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return &wm8350_irqs[irq - wm8350->irq_base];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * This is a threaded IRQ handler so can access I2C/SPI. Since all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * interrupts are clear on read the IRQ line will be reasserted and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * the physical IRQ will be handled again if another interrupt is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * asserted while we run - in the normal course of events this is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * rare occurrence so we save I2C/SPI reads. We're also assuming that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * it's rare to get lots of interrupts firing simultaneously so try to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * minimise I/O.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static irqreturn_t wm8350_irq(int irq, void *irq_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct wm8350 *wm8350 = irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) u16 level_one;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) u16 sub_reg[WM8350_NUM_IRQ_REGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int read_done[WM8350_NUM_IRQ_REGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct wm8350_irq_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!level_one)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) memset(&read_done, 0, sizeof(read_done));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) for (i = 0; i < ARRAY_SIZE(wm8350_irqs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) data = &wm8350_irqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (!(level_one & data->primary))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (!read_done[data->reg]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) sub_reg[data->reg] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) data->reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) sub_reg[data->reg] &= ~wm8350->irq_masks[data->reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) read_done[data->reg] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (sub_reg[data->reg] & data->mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) handle_nested_irq(wm8350->irq_base + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static void wm8350_irq_lock(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) mutex_lock(&wm8350->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static void wm8350_irq_sync_unlock(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* If there's been a change in the mask write it back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * to the hardware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) WARN_ON(regmap_update_bits(wm8350->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) WM8350_INT_STATUS_1_MASK + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 0xffff, wm8350->irq_masks[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) mutex_unlock(&wm8350->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static void wm8350_irq_enable(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) data->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static void wm8350_irq_disable(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) data->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) wm8350->irq_masks[irq_data->reg] |= irq_data->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static struct irq_chip wm8350_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .name = "wm8350",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .irq_bus_lock = wm8350_irq_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .irq_bus_sync_unlock = wm8350_irq_sync_unlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .irq_disable = wm8350_irq_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .irq_enable = wm8350_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int wm8350_irq_init(struct wm8350 *wm8350, int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct wm8350_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int ret, cur_irq, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int flags = IRQF_ONESHOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int irq_base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (!irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /* Mask top level interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* Mask all individual interrupts by default and cache the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * masks. We read the masks back since there are unwritable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * bits in the mask registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) wm8350->irq_masks[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) wm8350_reg_read(wm8350,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) WM8350_INT_STATUS_1_MASK + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) mutex_init(&wm8350->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) wm8350->chip_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (pdata && pdata->irq_base > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) irq_base = pdata->irq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) wm8350->irq_base =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) irq_alloc_descs(irq_base, 0, ARRAY_SIZE(wm8350_irqs), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (wm8350->irq_base < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) wm8350->irq_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (pdata && pdata->irq_high) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) flags |= IRQF_TRIGGER_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) WM8350_IRQ_POL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) flags |= IRQF_TRIGGER_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) WM8350_IRQ_POL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* Register with genirq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) for (cur_irq = wm8350->irq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) cur_irq++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) irq_set_chip_data(cur_irq, wm8350);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) irq_set_chip_and_handler(cur_irq, &wm8350_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) irq_set_nested_thread(cur_irq, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) irq_clear_status_flags(cur_irq, IRQ_NOREQUEST | IRQ_NOPROBE);
^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) ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) "wm8350", wm8350);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /* Allow interrupts to fire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return ret;
^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) int wm8350_irq_exit(struct wm8350 *wm8350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) free_irq(wm8350->chip_irq, wm8350);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }