Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sec-irq.c
Go to the documentation of this file.
1 /*
2  * sec-irq.c
3  *
4  * Copyright (c) 2011 Samsung Electronics Co., Ltd
5  * http://www.samsung.com
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2 of the License, or (at your
10  * option) any later version.
11  *
12  */
13 
14 #include <linux/device.h>
15 #include <linux/interrupt.h>
16 #include <linux/irq.h>
17 #include <linux/regmap.h>
18 
19 #include <linux/mfd/samsung/core.h>
20 #include <linux/mfd/samsung/irq.h>
24 
25 static struct regmap_irq s2mps11_irqs[] = {
26  [S2MPS11_IRQ_PWRONF] = {
27  .reg_offset = 1,
29  },
30  [S2MPS11_IRQ_PWRONR] = {
31  .reg_offset = 1,
33  },
35  .reg_offset = 1,
37  },
39  .reg_offset = 1,
41  },
42  [S2MPS11_IRQ_ACOKBF] = {
43  .reg_offset = 1,
45  },
46  [S2MPS11_IRQ_ACOKBR] = {
47  .reg_offset = 1,
49  },
51  .reg_offset = 1,
53  },
54  [S2MPS11_IRQ_MRB] = {
55  .reg_offset = 1,
56  .mask = S2MPS11_IRQ_MRB_MASK,
57  },
58  [S2MPS11_IRQ_RTC60S] = {
59  .reg_offset = 2,
61  },
62  [S2MPS11_IRQ_RTCA1] = {
63  .reg_offset = 2,
64  .mask = S2MPS11_IRQ_RTCA1_MASK,
65  },
66  [S2MPS11_IRQ_RTCA2] = {
67  .reg_offset = 2,
68  .mask = S2MPS11_IRQ_RTCA2_MASK,
69  },
70  [S2MPS11_IRQ_SMPL] = {
71  .reg_offset = 2,
72  .mask = S2MPS11_IRQ_SMPL_MASK,
73  },
74  [S2MPS11_IRQ_RTC1S] = {
75  .reg_offset = 2,
76  .mask = S2MPS11_IRQ_RTC1S_MASK,
77  },
78  [S2MPS11_IRQ_WTSR] = {
79  .reg_offset = 2,
80  .mask = S2MPS11_IRQ_WTSR_MASK,
81  },
83  .reg_offset = 3,
85  },
87  .reg_offset = 3,
89  },
90 };
91 
92 
93 static struct regmap_irq s5m8767_irqs[] = {
94  [S5M8767_IRQ_PWRR] = {
95  .reg_offset = 1,
96  .mask = S5M8767_IRQ_PWRR_MASK,
97  },
98  [S5M8767_IRQ_PWRF] = {
99  .reg_offset = 1,
100  .mask = S5M8767_IRQ_PWRF_MASK,
101  },
102  [S5M8767_IRQ_PWR1S] = {
103  .reg_offset = 1,
104  .mask = S5M8767_IRQ_PWR1S_MASK,
105  },
106  [S5M8767_IRQ_JIGR] = {
107  .reg_offset = 1,
108  .mask = S5M8767_IRQ_JIGR_MASK,
109  },
110  [S5M8767_IRQ_JIGF] = {
111  .reg_offset = 1,
112  .mask = S5M8767_IRQ_JIGF_MASK,
113  },
114  [S5M8767_IRQ_LOWBAT2] = {
115  .reg_offset = 1,
116  .mask = S5M8767_IRQ_LOWBAT2_MASK,
117  },
118  [S5M8767_IRQ_LOWBAT1] = {
119  .reg_offset = 1,
120  .mask = S5M8767_IRQ_LOWBAT1_MASK,
121  },
122  [S5M8767_IRQ_MRB] = {
123  .reg_offset = 2,
124  .mask = S5M8767_IRQ_MRB_MASK,
125  },
126  [S5M8767_IRQ_DVSOK2] = {
127  .reg_offset = 2,
128  .mask = S5M8767_IRQ_DVSOK2_MASK,
129  },
130  [S5M8767_IRQ_DVSOK3] = {
131  .reg_offset = 2,
132  .mask = S5M8767_IRQ_DVSOK3_MASK,
133  },
134  [S5M8767_IRQ_DVSOK4] = {
135  .reg_offset = 2,
136  .mask = S5M8767_IRQ_DVSOK4_MASK,
137  },
138  [S5M8767_IRQ_RTC60S] = {
139  .reg_offset = 3,
140  .mask = S5M8767_IRQ_RTC60S_MASK,
141  },
142  [S5M8767_IRQ_RTCA1] = {
143  .reg_offset = 3,
144  .mask = S5M8767_IRQ_RTCA1_MASK,
145  },
146  [S5M8767_IRQ_RTCA2] = {
147  .reg_offset = 3,
148  .mask = S5M8767_IRQ_RTCA2_MASK,
149  },
150  [S5M8767_IRQ_SMPL] = {
151  .reg_offset = 3,
152  .mask = S5M8767_IRQ_SMPL_MASK,
153  },
154  [S5M8767_IRQ_RTC1S] = {
155  .reg_offset = 3,
156  .mask = S5M8767_IRQ_RTC1S_MASK,
157  },
158  [S5M8767_IRQ_WTSR] = {
159  .reg_offset = 3,
160  .mask = S5M8767_IRQ_WTSR_MASK,
161  },
162 };
163 
164 static struct regmap_irq s5m8763_irqs[] = {
165  [S5M8763_IRQ_DCINF] = {
166  .reg_offset = 1,
167  .mask = S5M8763_IRQ_DCINF_MASK,
168  },
169  [S5M8763_IRQ_DCINR] = {
170  .reg_offset = 1,
171  .mask = S5M8763_IRQ_DCINR_MASK,
172  },
173  [S5M8763_IRQ_JIGF] = {
174  .reg_offset = 1,
175  .mask = S5M8763_IRQ_JIGF_MASK,
176  },
177  [S5M8763_IRQ_JIGR] = {
178  .reg_offset = 1,
179  .mask = S5M8763_IRQ_JIGR_MASK,
180  },
181  [S5M8763_IRQ_PWRONF] = {
182  .reg_offset = 1,
183  .mask = S5M8763_IRQ_PWRONF_MASK,
184  },
185  [S5M8763_IRQ_PWRONR] = {
186  .reg_offset = 1,
187  .mask = S5M8763_IRQ_PWRONR_MASK,
188  },
190  .reg_offset = 2,
192  },
194  .reg_offset = 2,
196  },
197  [S5M8763_IRQ_ALARM1] = {
198  .reg_offset = 2,
199  .mask = S5M8763_IRQ_ALARM1_MASK,
200  },
201  [S5M8763_IRQ_ALARM0] = {
202  .reg_offset = 2,
203  .mask = S5M8763_IRQ_ALARM0_MASK,
204  },
205  [S5M8763_IRQ_ONKEY1S] = {
206  .reg_offset = 3,
207  .mask = S5M8763_IRQ_ONKEY1S_MASK,
208  },
209  [S5M8763_IRQ_TOPOFFR] = {
210  .reg_offset = 3,
211  .mask = S5M8763_IRQ_TOPOFFR_MASK,
212  },
214  .reg_offset = 3,
216  },
217  [S5M8763_IRQ_CHGRSTF] = {
218  .reg_offset = 3,
219  .mask = S5M8763_IRQ_CHGRSTF_MASK,
220  },
221  [S5M8763_IRQ_DONER] = {
222  .reg_offset = 3,
223  .mask = S5M8763_IRQ_DONER_MASK,
224  },
226  .reg_offset = 3,
228  },
229  [S5M8763_IRQ_LOBAT1] = {
230  .reg_offset = 4,
231  .mask = S5M8763_IRQ_LOBAT1_MASK,
232  },
233  [S5M8763_IRQ_LOBAT2] = {
234  .reg_offset = 4,
235  .mask = S5M8763_IRQ_LOBAT2_MASK,
236  },
237 };
238 
239 static struct regmap_irq_chip s2mps11_irq_chip = {
240  .name = "s2mps11",
241  .irqs = s2mps11_irqs,
242  .num_irqs = ARRAY_SIZE(s2mps11_irqs),
243  .num_regs = 3,
244  .status_base = S2MPS11_REG_INT1,
245  .mask_base = S2MPS11_REG_INT1M,
246  .ack_base = S2MPS11_REG_INT1,
247 };
248 
249 static struct regmap_irq_chip s5m8767_irq_chip = {
250  .name = "s5m8767",
251  .irqs = s5m8767_irqs,
252  .num_irqs = ARRAY_SIZE(s5m8767_irqs),
253  .num_regs = 3,
254  .status_base = S5M8767_REG_INT1,
255  .mask_base = S5M8767_REG_INT1M,
256  .ack_base = S5M8767_REG_INT1,
257 };
258 
259 static struct regmap_irq_chip s5m8763_irq_chip = {
260  .name = "s5m8763",
261  .irqs = s5m8763_irqs,
262  .num_irqs = ARRAY_SIZE(s5m8763_irqs),
263  .num_regs = 4,
264  .status_base = S5M8763_REG_IRQ1,
265  .mask_base = S5M8763_REG_IRQM1,
266  .ack_base = S5M8763_REG_IRQ1,
267 };
268 
269 int sec_irq_init(struct sec_pmic_dev *sec_pmic)
270 {
271  int ret = 0;
272  int type = sec_pmic->device_type;
273 
274  if (!sec_pmic->irq) {
275  dev_warn(sec_pmic->dev,
276  "No interrupt specified, no interrupts\n");
277  sec_pmic->irq_base = 0;
278  return 0;
279  }
280 
281  switch (type) {
282  case S5M8763X:
283  ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
285  sec_pmic->irq_base, &s5m8763_irq_chip,
286  &sec_pmic->irq_data);
287  break;
288  case S5M8767X:
289  ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
291  sec_pmic->irq_base, &s5m8767_irq_chip,
292  &sec_pmic->irq_data);
293  break;
294  case S2MPS11X:
295  ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
297  sec_pmic->irq_base, &s2mps11_irq_chip,
298  &sec_pmic->irq_data);
299  break;
300  default:
301  dev_err(sec_pmic->dev, "Unknown device type %d\n",
302  sec_pmic->device_type);
303  return -EINVAL;
304  }
305 
306  if (ret != 0) {
307  dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
308  return ret;
309  }
310 
311  return 0;
312 }
313 
314 void sec_irq_exit(struct sec_pmic_dev *sec_pmic)
315 {
316  regmap_del_irq_chip(sec_pmic->irq, sec_pmic->irq_data);
317 }