2 #include <linux/kernel.h>
3 #include <linux/module.h>
6 #include <linux/mfd/core.h>
7 #include <linux/interrupt.h>
9 #include <linux/mfd/tlv320aic3262-core.h>
10 #include <linux/mfd/tlv320aic3262-registers.h>
12 #include <linux/delay.h>
13 struct aic3262_irq_data {
18 static struct aic3262_irq_data aic3262_irqs[] = {
20 .mask = AIC3262_HEADSET_IN_MASK,
21 .status = AIC3262_HEADSET_PLUG_UNPLUG_INT,
24 .mask = AIC3262_BUTTON_PRESS_MASK,
25 .status = AIC3262_BUTTON_PRESS_INT,
28 .mask = AIC3262_DAC_DRC_THRES_MASK,
29 .status = AIC3262_LEFT_DRC_THRES_INT | AIC3262_RIGHT_DRC_THRES_INT,
32 .mask = AIC3262_AGC_NOISE_MASK,
33 .status = AIC3262_LEFT_AGC_NOISE_INT | AIC3262_RIGHT_AGC_NOISE_INT,
36 .mask = AIC3262_OVER_CURRENT_MASK,
37 .status = AIC3262_LEFT_OUTPUT_DRIVER_OVERCURRENT_INT
38 | AIC3262_RIGHT_OUTPUT_DRIVER_OVERCURRENT_INT,
41 .mask = AIC3262_OVERFLOW_MASK,
42 .status = AIC3262_LEFT_DAC_OVERFLOW_INT | AIC3262_RIGHT_DAC_OVERFLOW_INT
43 | AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT | AIC3262_LEFT_ADC_OVERFLOW_INT
44 | AIC3262_RIGHT_ADC_OVERFLOW_INT | AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT,
47 .mask = AIC3262_SPK_OVERCURRENT_MASK,
48 .status = AIC3262_SPK_OVER_CURRENT_INT,
53 struct aic3262_gpio_data {
57 static inline struct aic3262_irq_data *irq_to_aic3262_irq(struct aic3262 *aic3262,
60 return &aic3262_irqs[irq - aic3262->irq_base];
63 static void aic3262_irq_lock(struct irq_data *data)
65 struct aic3262 *aic3262 = irq_data_get_irq_chip_data(data);
67 mutex_lock(&aic3262->irq_lock);
70 static void aic3262_irq_sync_unlock(struct irq_data *data)
72 struct aic3262 *aic3262 = irq_data_get_irq_chip_data(data);
74 /* write back to hardware any change in irq mask */
75 if (aic3262->irq_masks_cur != aic3262->irq_masks_cache) {
76 aic3262->irq_masks_cache = aic3262->irq_masks_cur;
77 aic3262_reg_write(aic3262, AIC3262_INT1_CNTL,
78 aic3262->irq_masks_cur);
81 mutex_unlock(&aic3262->irq_lock);
84 static void aic3262_irq_unmask(struct irq_data *data)
86 struct aic3262 *aic3262 = irq_data_get_irq_chip_data(data);
87 struct aic3262_irq_data *irq_data = irq_to_aic3262_irq(aic3262, data->irq);
89 aic3262->irq_masks_cur |= irq_data->mask;
92 static void aic3262_irq_mask(struct irq_data *data)
94 struct aic3262 *aic3262 = irq_data_get_irq_chip_data(data);
95 struct aic3262_irq_data *irq_data = irq_to_aic3262_irq(aic3262, data->irq);
97 aic3262->irq_masks_cur &= ~irq_data->mask;
100 static struct irq_chip aic3262_irq_chip = {
101 .name = "tlv320aic3262",
102 .irq_bus_lock = aic3262_irq_lock,
103 .irq_bus_sync_unlock = aic3262_irq_sync_unlock,
104 .irq_mask = aic3262_irq_mask,
105 .irq_unmask = aic3262_irq_unmask,
108 static irqreturn_t aic3262_irq_thread(int irq, void *data)
110 struct aic3262 *aic3262 = data;
113 // Reading the sticky bit registers acknowledges the interrupt to the device */
114 aic3262_bulk_read(aic3262, AIC3262_INT_STICKY_FLAG1, 4, status);
117 if(status[2] & aic3262_irqs[AIC3262_IRQ_HEADSET_DETECT].status) // 0
119 handle_nested_irq(aic3262->irq_base);
122 if(status[2] & aic3262_irqs[AIC3262_IRQ_BUTTON_PRESS].status) // 1
123 handle_nested_irq(aic3262->irq_base + 1);
124 if(status[2] & aic3262_irqs[AIC3262_IRQ_DAC_DRC].status) // 2
125 handle_nested_irq(aic3262->irq_base + 2);
126 if(status[3] & aic3262_irqs[AIC3262_IRQ_AGC_NOISE].status) // 3
127 handle_nested_irq(aic3262->irq_base + 3);
128 if(status[2] & aic3262_irqs[AIC3262_IRQ_OVER_CURRENT].status) // 4
129 handle_nested_irq(aic3262->irq_base + 4);
130 if(status[0] & aic3262_irqs[AIC3262_IRQ_OVERFLOW_EVENT].status) // 5
131 handle_nested_irq(aic3262->irq_base + 5);
132 if(status[3] & aic3262_irqs[AIC3262_IRQ_SPEAKER_OVER_TEMP].status) // 6
133 handle_nested_irq(aic3262->irq_base + 6);
135 /* ack unmasked irqs */
136 /* No need to acknowledge the interrupt on AIC3262 */
143 int aic3262_irq_init(struct aic3262 *aic3262)
147 mutex_init(&aic3262->irq_lock);
149 /* mask the individual interrupt sources */
150 aic3262->irq_masks_cur = 0x0;
151 aic3262->irq_masks_cache = 0x0;
152 aic3262_reg_write(aic3262, AIC3262_INT1_CNTL, 0x0);
155 dev_warn(aic3262->dev,
156 "no interrupt specified, no interrupts\n");
157 aic3262->irq_base = 0;
161 if (!aic3262->irq_base) {
162 dev_err(aic3262->dev,
163 "no interrupt base specified, no interrupts\n");
168 /* Register them with genirq */
169 for (cur_irq = aic3262->irq_base;
170 cur_irq < aic3262->irq_base + ARRAY_SIZE(aic3262_irqs);
172 irq_set_chip_data(cur_irq, aic3262);
173 irq_set_chip_and_handler(cur_irq, &aic3262_irq_chip,
175 irq_set_nested_thread(cur_irq, 1);
177 /* ARM needs us to explicitly flag the IRQ as valid
178 * and will set them noprobe when we do so. */
180 set_irq_flags(cur_irq, IRQF_VALID);
182 set_irq_noprobe(cur_irq);
186 ret = request_threaded_irq(aic3262->irq, NULL, aic3262_irq_thread,
188 "tlv320aic3262", aic3262);
190 dev_err(aic3262->dev, "failed to request IRQ %d: %d\n",
197 EXPORT_SYMBOL(aic3262_irq_init);
199 void aic3262_irq_exit(struct aic3262 *aic3262)
202 free_irq(aic3262->irq, aic3262);
204 EXPORT_SYMBOL(aic3262_irq_exit);