aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-i2c-devices-fsa948021
-rw-r--r--drivers/misc/Kconfig9
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/fsa9480.c557
-rw-r--r--include/linux/platform_data/fsa9480.h27
5 files changed, 615 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-i2c-devices-fsa9480 b/Documentation/ABI/testing/sysfs-bus-i2c-devices-fsa9480
new file mode 100644
index 000000000000..9de269bb0ae5
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-fsa9480
@@ -0,0 +1,21 @@
1What: /sys/bus/i2c/devices/.../device
2Date: February 2011
3Contact: Minkyu Kang <mk7.kang@samsung.com>
4Description:
5 show what device is attached
6 NONE - no device
7 USB - USB device is attached
8 UART - UART is attached
9 CHARGER - Charger is attaced
10 JIG - JIG is attached
11
12What: /sys/bus/i2c/devices/.../switch
13Date: February 2011
14Contact: Minkyu Kang <mk7.kang@samsung.com>
15Description:
16 show or set the state of manual switch
17 VAUDIO - switch to VAUDIO path
18 UART - switch to UART path
19 AUDIO - switch to AUDIO path
20 DHOST - switch to DHOST path
21 AUTO - switch automatically by device
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 3546474428f8..0a4d86c6c4a4 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -489,6 +489,15 @@ config PCH_PHUB
489 To compile this driver as a module, choose M here: the module will 489 To compile this driver as a module, choose M here: the module will
490 be called pch_phub. 490 be called pch_phub.
491 491
492config USB_SWITCH_FSA9480
493 tristate "FSA9480 USB Switch"
494 depends on I2C
495 help
496 The FSA9480 is a USB port accessory detector and switch.
497 The FSA9480 is fully controlled using I2C and enables USB data,
498 stereo and mono audio, video, microphone and UART data to use
499 a common connector port.
500
492source "drivers/misc/c2port/Kconfig" 501source "drivers/misc/c2port/Kconfig"
493source "drivers/misc/eeprom/Kconfig" 502source "drivers/misc/eeprom/Kconfig"
494source "drivers/misc/cb710/Kconfig" 503source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 5f03172cc0b5..33282157bc3c 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -46,3 +46,4 @@ obj-y += ti-st/
46obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o 46obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o
47obj-y += lis3lv02d/ 47obj-y += lis3lv02d/
48obj-y += carma/ 48obj-y += carma/
49obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c
new file mode 100644
index 000000000000..5325a7e70dcf
--- /dev/null
+++ b/drivers/misc/fsa9480.c
@@ -0,0 +1,557 @@
1/*
2 * fsa9480.c - FSA9480 micro USB switch device driver
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 * Minkyu Kang <mk7.kang@samsung.com>
6 * Wonguk Jeong <wonguk.jeong@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/err.h>
16#include <linux/i2c.h>
17#include <linux/platform_data/fsa9480.h>
18#include <linux/irq.h>
19#include <linux/interrupt.h>
20#include <linux/workqueue.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/pm_runtime.h>
24
25/* FSA9480 I2C registers */
26#define FSA9480_REG_DEVID 0x01
27#define FSA9480_REG_CTRL 0x02
28#define FSA9480_REG_INT1 0x03
29#define FSA9480_REG_INT2 0x04
30#define FSA9480_REG_INT1_MASK 0x05
31#define FSA9480_REG_INT2_MASK 0x06
32#define FSA9480_REG_ADC 0x07
33#define FSA9480_REG_TIMING1 0x08
34#define FSA9480_REG_TIMING2 0x09
35#define FSA9480_REG_DEV_T1 0x0a
36#define FSA9480_REG_DEV_T2 0x0b
37#define FSA9480_REG_BTN1 0x0c
38#define FSA9480_REG_BTN2 0x0d
39#define FSA9480_REG_CK 0x0e
40#define FSA9480_REG_CK_INT1 0x0f
41#define FSA9480_REG_CK_INT2 0x10
42#define FSA9480_REG_CK_INTMASK1 0x11
43#define FSA9480_REG_CK_INTMASK2 0x12
44#define FSA9480_REG_MANSW1 0x13
45#define FSA9480_REG_MANSW2 0x14
46
47/* Control */
48#define CON_SWITCH_OPEN (1 << 4)
49#define CON_RAW_DATA (1 << 3)
50#define CON_MANUAL_SW (1 << 2)
51#define CON_WAIT (1 << 1)
52#define CON_INT_MASK (1 << 0)
53#define CON_MASK (CON_SWITCH_OPEN | CON_RAW_DATA | \
54 CON_MANUAL_SW | CON_WAIT)
55
56/* Device Type 1 */
57#define DEV_USB_OTG (1 << 7)
58#define DEV_DEDICATED_CHG (1 << 6)
59#define DEV_USB_CHG (1 << 5)
60#define DEV_CAR_KIT (1 << 4)
61#define DEV_UART (1 << 3)
62#define DEV_USB (1 << 2)
63#define DEV_AUDIO_2 (1 << 1)
64#define DEV_AUDIO_1 (1 << 0)
65
66#define DEV_T1_USB_MASK (DEV_USB_OTG | DEV_USB)
67#define DEV_T1_UART_MASK (DEV_UART)
68#define DEV_T1_CHARGER_MASK (DEV_DEDICATED_CHG | DEV_USB_CHG)
69
70/* Device Type 2 */
71#define DEV_AV (1 << 6)
72#define DEV_TTY (1 << 5)
73#define DEV_PPD (1 << 4)
74#define DEV_JIG_UART_OFF (1 << 3)
75#define DEV_JIG_UART_ON (1 << 2)
76#define DEV_JIG_USB_OFF (1 << 1)
77#define DEV_JIG_USB_ON (1 << 0)
78
79#define DEV_T2_USB_MASK (DEV_JIG_USB_OFF | DEV_JIG_USB_ON)
80#define DEV_T2_UART_MASK (DEV_JIG_UART_OFF | DEV_JIG_UART_ON)
81#define DEV_T2_JIG_MASK (DEV_JIG_USB_OFF | DEV_JIG_USB_ON | \
82 DEV_JIG_UART_OFF | DEV_JIG_UART_ON)
83
84/*
85 * Manual Switch
86 * D- [7:5] / D+ [4:2]
87 * 000: Open all / 001: USB / 010: AUDIO / 011: UART / 100: V_AUDIO
88 */
89#define SW_VAUDIO ((4 << 5) | (4 << 2))
90#define SW_UART ((3 << 5) | (3 << 2))
91#define SW_AUDIO ((2 << 5) | (2 << 2))
92#define SW_DHOST ((1 << 5) | (1 << 2))
93#define SW_AUTO ((0 << 5) | (0 << 2))
94
95/* Interrupt 1 */
96#define INT_DETACH (1 << 1)
97#define INT_ATTACH (1 << 0)
98
99struct fsa9480_usbsw {
100 struct i2c_client *client;
101 struct fsa9480_platform_data *pdata;
102 int dev1;
103 int dev2;
104 int mansw;
105};
106
107static struct fsa9480_usbsw *chip;
108
109static int fsa9480_write_reg(struct i2c_client *client,
110 int reg, int value)
111{
112 int ret;
113
114 ret = i2c_smbus_write_byte_data(client, reg, value);
115
116 if (ret < 0)
117 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
118
119 return ret;
120}
121
122static int fsa9480_read_reg(struct i2c_client *client, int reg)
123{
124 int ret;
125
126 ret = i2c_smbus_read_byte_data(client, reg);
127
128 if (ret < 0)
129 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
130
131 return ret;
132}
133
134static int fsa9480_read_irq(struct i2c_client *client, int *value)
135{
136 int ret;
137
138 ret = i2c_smbus_read_i2c_block_data(client,
139 FSA9480_REG_INT1, 2, (u8 *)value);
140 *value &= 0xffff;
141
142 if (ret < 0)
143 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
144
145 return ret;
146}
147
148static void fsa9480_set_switch(const char *buf)
149{
150 struct fsa9480_usbsw *usbsw = chip;
151 struct i2c_client *client = usbsw->client;
152 unsigned int value;
153 unsigned int path = 0;
154
155 value = fsa9480_read_reg(client, FSA9480_REG_CTRL);
156
157 if (!strncmp(buf, "VAUDIO", 6)) {
158 path = SW_VAUDIO;
159 value &= ~CON_MANUAL_SW;
160 } else if (!strncmp(buf, "UART", 4)) {
161 path = SW_UART;
162 value &= ~CON_MANUAL_SW;
163 } else if (!strncmp(buf, "AUDIO", 5)) {
164 path = SW_AUDIO;
165 value &= ~CON_MANUAL_SW;
166 } else if (!strncmp(buf, "DHOST", 5)) {
167 path = SW_DHOST;
168 value &= ~CON_MANUAL_SW;
169 } else if (!strncmp(buf, "AUTO", 4)) {
170 path = SW_AUTO;
171 value |= CON_MANUAL_SW;
172 } else {
173 printk(KERN_ERR "Wrong command\n");
174 return;
175 }
176
177 usbsw->mansw = path;
178 fsa9480_write_reg(client, FSA9480_REG_MANSW1, path);
179 fsa9480_write_reg(client, FSA9480_REG_CTRL, value);
180}
181
182static ssize_t fsa9480_get_switch(char *buf)
183{
184 struct fsa9480_usbsw *usbsw = chip;
185 struct i2c_client *client = usbsw->client;
186 unsigned int value;
187
188 value = fsa9480_read_reg(client, FSA9480_REG_MANSW1);
189
190 if (value == SW_VAUDIO)
191 return sprintf(buf, "VAUDIO\n");
192 else if (value == SW_UART)
193 return sprintf(buf, "UART\n");
194 else if (value == SW_AUDIO)
195 return sprintf(buf, "AUDIO\n");
196 else if (value == SW_DHOST)
197 return sprintf(buf, "DHOST\n");
198 else if (value == SW_AUTO)
199 return sprintf(buf, "AUTO\n");
200 else
201 return sprintf(buf, "%x", value);
202}
203
204static ssize_t fsa9480_show_device(struct device *dev,
205 struct device_attribute *attr,
206 char *buf)
207{
208 struct fsa9480_usbsw *usbsw = dev_get_drvdata(dev);
209 struct i2c_client *client = usbsw->client;
210 int dev1, dev2;
211
212 dev1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1);
213 dev2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2);
214
215 if (!dev1 && !dev2)
216 return sprintf(buf, "NONE\n");
217
218 /* USB */
219 if (dev1 & DEV_T1_USB_MASK || dev2 & DEV_T2_USB_MASK)
220 return sprintf(buf, "USB\n");
221
222 /* UART */
223 if (dev1 & DEV_T1_UART_MASK || dev2 & DEV_T2_UART_MASK)
224 return sprintf(buf, "UART\n");
225
226 /* CHARGER */
227 if (dev1 & DEV_T1_CHARGER_MASK)
228 return sprintf(buf, "CHARGER\n");
229
230 /* JIG */
231 if (dev2 & DEV_T2_JIG_MASK)
232 return sprintf(buf, "JIG\n");
233
234 return sprintf(buf, "UNKNOWN\n");
235}
236
237static ssize_t fsa9480_show_manualsw(struct device *dev,
238 struct device_attribute *attr, char *buf)
239{
240 return fsa9480_get_switch(buf);
241
242}
243
244static ssize_t fsa9480_set_manualsw(struct device *dev,
245 struct device_attribute *attr,
246 const char *buf, size_t count)
247{
248 fsa9480_set_switch(buf);
249
250 return count;
251}
252
253static DEVICE_ATTR(device, S_IRUGO, fsa9480_show_device, NULL);
254static DEVICE_ATTR(switch, S_IRUGO | S_IWUSR,
255 fsa9480_show_manualsw, fsa9480_set_manualsw);
256
257static struct attribute *fsa9480_attributes[] = {
258 &dev_attr_device.attr,
259 &dev_attr_switch.attr,
260 NULL
261};
262
263static const struct attribute_group fsa9480_group = {
264 .attrs = fsa9480_attributes,
265};
266
267static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw, int intr)
268{
269 int val1, val2, ctrl;
270 struct fsa9480_platform_data *pdata = usbsw->pdata;
271 struct i2c_client *client = usbsw->client;
272
273 val1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1);
274 val2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2);
275 ctrl = fsa9480_read_reg(client, FSA9480_REG_CTRL);
276
277 dev_info(&client->dev, "intr: 0x%x, dev1: 0x%x, dev2: 0x%x\n",
278 intr, val1, val2);
279
280 if (!intr)
281 goto out;
282
283 if (intr & INT_ATTACH) { /* Attached */
284 /* USB */
285 if (val1 & DEV_T1_USB_MASK || val2 & DEV_T2_USB_MASK) {
286 if (pdata->usb_cb)
287 pdata->usb_cb(FSA9480_ATTACHED);
288
289 if (usbsw->mansw) {
290 fsa9480_write_reg(client,
291 FSA9480_REG_MANSW1, usbsw->mansw);
292 }
293 }
294
295 /* UART */
296 if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) {
297 if (pdata->uart_cb)
298 pdata->uart_cb(FSA9480_ATTACHED);
299
300 if (!(ctrl & CON_MANUAL_SW)) {
301 fsa9480_write_reg(client,
302 FSA9480_REG_MANSW1, SW_UART);
303 }
304 }
305
306 /* CHARGER */
307 if (val1 & DEV_T1_CHARGER_MASK) {
308 if (pdata->charger_cb)
309 pdata->charger_cb(FSA9480_ATTACHED);
310 }
311
312 /* JIG */
313 if (val2 & DEV_T2_JIG_MASK) {
314 if (pdata->jig_cb)
315 pdata->jig_cb(FSA9480_ATTACHED);
316 }
317 } else if (intr & INT_DETACH) { /* Detached */
318 /* USB */
319 if (usbsw->dev1 & DEV_T1_USB_MASK ||
320 usbsw->dev2 & DEV_T2_USB_MASK) {
321 if (pdata->usb_cb)
322 pdata->usb_cb(FSA9480_DETACHED);
323 }
324
325 /* UART */
326 if (usbsw->dev1 & DEV_T1_UART_MASK ||
327 usbsw->dev2 & DEV_T2_UART_MASK) {
328 if (pdata->uart_cb)
329 pdata->uart_cb(FSA9480_DETACHED);
330 }
331
332 /* CHARGER */
333 if (usbsw->dev1 & DEV_T1_CHARGER_MASK) {
334 if (pdata->charger_cb)
335 pdata->charger_cb(FSA9480_DETACHED);
336 }
337
338 /* JIG */
339 if (usbsw->dev2 & DEV_T2_JIG_MASK) {
340 if (pdata->jig_cb)
341 pdata->jig_cb(FSA9480_DETACHED);
342 }
343 }
344
345 usbsw->dev1 = val1;
346 usbsw->dev2 = val2;
347
348out:
349 ctrl &= ~CON_INT_MASK;
350 fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl);
351}
352
353static irqreturn_t fsa9480_irq_handler(int irq, void *data)
354{
355 struct fsa9480_usbsw *usbsw = data;
356 struct i2c_client *client = usbsw->client;
357 int intr;
358
359 /* clear interrupt */
360 fsa9480_read_irq(client, &intr);
361
362 /* device detection */
363 fsa9480_detect_dev(usbsw, intr);
364
365 return IRQ_HANDLED;
366}
367
368static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw)
369{
370 struct fsa9480_platform_data *pdata = usbsw->pdata;
371 struct i2c_client *client = usbsw->client;
372 int ret;
373 int intr;
374 unsigned int ctrl = CON_MASK;
375
376 /* clear interrupt */
377 fsa9480_read_irq(client, &intr);
378
379 /* unmask interrupt (attach/detach only) */
380 fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0xfc);
381 fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x1f);
382
383 usbsw->mansw = fsa9480_read_reg(client, FSA9480_REG_MANSW1);
384
385 if (usbsw->mansw)
386 ctrl &= ~CON_MANUAL_SW; /* Manual Switching Mode */
387
388 fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl);
389
390 if (pdata && pdata->cfg_gpio)
391 pdata->cfg_gpio();
392
393 if (client->irq) {
394 ret = request_threaded_irq(client->irq, NULL,
395 fsa9480_irq_handler,
396 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
397 "fsa9480 micro USB", usbsw);
398 if (ret) {
399 dev_err(&client->dev, "failed to reqeust IRQ\n");
400 return ret;
401 }
402
403 device_init_wakeup(&client->dev, pdata->wakeup);
404 }
405
406 return 0;
407}
408
409static int __devinit fsa9480_probe(struct i2c_client *client,
410 const struct i2c_device_id *id)
411{
412 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
413 struct fsa9480_usbsw *usbsw;
414 int ret = 0;
415
416 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
417 return -EIO;
418
419 usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL);
420 if (!usbsw) {
421 dev_err(&client->dev, "failed to allocate driver data\n");
422 return -ENOMEM;
423 }
424
425 usbsw->client = client;
426 usbsw->pdata = client->dev.platform_data;
427
428 chip = usbsw;
429
430 i2c_set_clientdata(client, usbsw);
431
432 ret = fsa9480_irq_init(usbsw);
433 if (ret)
434 goto fail1;
435
436 ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group);
437 if (ret) {
438 dev_err(&client->dev,
439 "failed to create fsa9480 attribute group\n");
440 goto fail2;
441 }
442
443 /* ADC Detect Time: 500ms */
444 fsa9480_write_reg(client, FSA9480_REG_TIMING1, 0x6);
445
446 if (chip->pdata->reset_cb)
447 chip->pdata->reset_cb();
448
449 /* device detection */
450 fsa9480_detect_dev(usbsw, INT_ATTACH);
451
452 pm_runtime_set_active(&client->dev);
453
454 return 0;
455
456fail2:
457 if (client->irq)
458 free_irq(client->irq, NULL);
459fail1:
460 i2c_set_clientdata(client, NULL);
461 kfree(usbsw);
462 return ret;
463}
464
465static int __devexit fsa9480_remove(struct i2c_client *client)
466{
467 struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
468 if (client->irq)
469 free_irq(client->irq, NULL);
470 i2c_set_clientdata(client, NULL);
471
472 sysfs_remove_group(&client->dev.kobj, &fsa9480_group);
473 device_init_wakeup(&client->dev, 0);
474 kfree(usbsw);
475 return 0;
476}
477
478#ifdef CONFIG_PM
479
480static int fsa9480_suspend(struct i2c_client *client, pm_message_t state)
481{
482 struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
483 struct fsa9480_platform_data *pdata = usbsw->pdata;
484
485 if (device_may_wakeup(&client->dev) && client->irq)
486 enable_irq_wake(client->irq);
487
488 if (pdata->usb_power)
489 pdata->usb_power(0);
490
491 return 0;
492}
493
494static int fsa9480_resume(struct i2c_client *client)
495{
496 struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
497 int dev1, dev2;
498
499 if (device_may_wakeup(&client->dev) && client->irq)
500 disable_irq_wake(client->irq);
501
502 /*
503 * Clear Pending interrupt. Note that detect_dev does what
504 * the interrupt handler does. So, we don't miss pending and
505 * we reenable interrupt if there is one.
506 */
507 fsa9480_read_reg(client, FSA9480_REG_INT1);
508 fsa9480_read_reg(client, FSA9480_REG_INT2);
509
510 dev1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1);
511 dev2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2);
512
513 /* device detection */
514 fsa9480_detect_dev(usbsw, (dev1 || dev2) ? INT_ATTACH : INT_DETACH);
515
516 return 0;
517}
518
519#else
520
521#define fsa9480_suspend NULL
522#define fsa9480_resume NULL
523
524#endif /* CONFIG_PM */
525
526static const struct i2c_device_id fsa9480_id[] = {
527 {"fsa9480", 0},
528 {}
529};
530MODULE_DEVICE_TABLE(i2c, fsa9480_id);
531
532static struct i2c_driver fsa9480_i2c_driver = {
533 .driver = {
534 .name = "fsa9480",
535 },
536 .probe = fsa9480_probe,
537 .remove = __devexit_p(fsa9480_remove),
538 .resume = fsa9480_resume,
539 .suspend = fsa9480_suspend,
540 .id_table = fsa9480_id,
541};
542
543static int __init fsa9480_init(void)
544{
545 return i2c_add_driver(&fsa9480_i2c_driver);
546}
547module_init(fsa9480_init);
548
549static void __exit fsa9480_exit(void)
550{
551 i2c_del_driver(&fsa9480_i2c_driver);
552}
553module_exit(fsa9480_exit);
554
555MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
556MODULE_DESCRIPTION("FSA9480 USB Switch driver");
557MODULE_LICENSE("GPL");
diff --git a/include/linux/platform_data/fsa9480.h b/include/linux/platform_data/fsa9480.h
new file mode 100644
index 000000000000..72dddcb4bed1
--- /dev/null
+++ b/include/linux/platform_data/fsa9480.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics
3 * Minkyu Kang <mk7.kang@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#ifndef _FSA9480_H_
11#define _FSA9480_H_
12
13#define FSA9480_ATTACHED 1
14#define FSA9480_DETACHED 0
15
16struct fsa9480_platform_data {
17 void (*cfg_gpio) (void);
18 void (*usb_cb) (u8 attached);
19 void (*uart_cb) (u8 attached);
20 void (*charger_cb) (u8 attached);
21 void (*jig_cb) (u8 attached);
22 void (*reset_cb) (void);
23 void (*usb_power) (u8 on);
24 int wakeup;
25};
26
27#endif /* _FSA9480_H_ */