diff options
Diffstat (limited to 'arch/arm/mach-s3c2410/h1940-bluetooth.c')
-rw-r--r-- | arch/arm/mach-s3c2410/h1940-bluetooth.c | 88 |
1 files changed, 42 insertions, 46 deletions
diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c index 5aabf117cbb0..b7d1f8d27bc2 100644 --- a/arch/arm/mach-s3c2410/h1940-bluetooth.c +++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/ctype.h> | 17 | #include <linux/ctype.h> |
18 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
20 | #include <linux/rfkill.h> | ||
20 | 21 | ||
21 | #include <mach/regs-gpio.h> | 22 | #include <mach/regs-gpio.h> |
22 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
@@ -24,21 +25,10 @@ | |||
24 | 25 | ||
25 | #define DRV_NAME "h1940-bt" | 26 | #define DRV_NAME "h1940-bt" |
26 | 27 | ||
27 | #ifdef CONFIG_LEDS_H1940 | ||
28 | DEFINE_LED_TRIGGER(bt_led_trigger); | ||
29 | #endif | ||
30 | |||
31 | static int state; | ||
32 | |||
33 | /* Bluetooth control */ | 28 | /* Bluetooth control */ |
34 | static void h1940bt_enable(int on) | 29 | static void h1940bt_enable(int on) |
35 | { | 30 | { |
36 | if (on) { | 31 | if (on) { |
37 | #ifdef CONFIG_LEDS_H1940 | ||
38 | /* flashing Blue */ | ||
39 | led_trigger_event(bt_led_trigger, LED_HALF); | ||
40 | #endif | ||
41 | |||
42 | /* Power on the chip */ | 32 | /* Power on the chip */ |
43 | h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER); | 33 | h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER); |
44 | /* Reset the chip */ | 34 | /* Reset the chip */ |
@@ -46,48 +36,31 @@ static void h1940bt_enable(int on) | |||
46 | s3c2410_gpio_setpin(S3C2410_GPH(1), 1); | 36 | s3c2410_gpio_setpin(S3C2410_GPH(1), 1); |
47 | mdelay(10); | 37 | mdelay(10); |
48 | s3c2410_gpio_setpin(S3C2410_GPH(1), 0); | 38 | s3c2410_gpio_setpin(S3C2410_GPH(1), 0); |
49 | |||
50 | state = 1; | ||
51 | } | 39 | } |
52 | else { | 40 | else { |
53 | #ifdef CONFIG_LEDS_H1940 | ||
54 | led_trigger_event(bt_led_trigger, 0); | ||
55 | #endif | ||
56 | |||
57 | s3c2410_gpio_setpin(S3C2410_GPH(1), 1); | 41 | s3c2410_gpio_setpin(S3C2410_GPH(1), 1); |
58 | mdelay(10); | 42 | mdelay(10); |
59 | s3c2410_gpio_setpin(S3C2410_GPH(1), 0); | 43 | s3c2410_gpio_setpin(S3C2410_GPH(1), 0); |
60 | mdelay(10); | 44 | mdelay(10); |
61 | h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0); | 45 | h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0); |
62 | |||
63 | state = 0; | ||
64 | } | 46 | } |
65 | } | 47 | } |
66 | 48 | ||
67 | static ssize_t h1940bt_show(struct device *dev, struct device_attribute *attr, char *buf) | 49 | static int h1940bt_set_block(void *data, bool blocked) |
68 | { | 50 | { |
69 | return snprintf(buf, PAGE_SIZE, "%d\n", state); | 51 | h1940bt_enable(!blocked); |
52 | return 0; | ||
70 | } | 53 | } |
71 | 54 | ||
72 | static ssize_t h1940bt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 55 | static const struct rfkill_ops h1940bt_rfkill_ops = { |
73 | { | 56 | .set_block = h1940bt_set_block, |
74 | int new_state; | 57 | }; |
75 | char *endp; | ||
76 | |||
77 | new_state = simple_strtoul(buf, &endp, 0); | ||
78 | if (*endp && !isspace(*endp)) | ||
79 | return -EINVAL; | ||
80 | |||
81 | h1940bt_enable(new_state); | ||
82 | |||
83 | return count; | ||
84 | } | ||
85 | static DEVICE_ATTR(enable, 0644, | ||
86 | h1940bt_show, | ||
87 | h1940bt_store); | ||
88 | 58 | ||
89 | static int __init h1940bt_probe(struct platform_device *pdev) | 59 | static int __init h1940bt_probe(struct platform_device *pdev) |
90 | { | 60 | { |
61 | struct rfkill *rfk; | ||
62 | int ret = 0; | ||
63 | |||
91 | /* Configures BT serial port GPIOs */ | 64 | /* Configures BT serial port GPIOs */ |
92 | s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); | 65 | s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); |
93 | s3c2410_gpio_pullup(S3C2410_GPH(0), 1); | 66 | s3c2410_gpio_pullup(S3C2410_GPH(0), 1); |
@@ -98,21 +71,44 @@ static int __init h1940bt_probe(struct platform_device *pdev) | |||
98 | s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); | 71 | s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); |
99 | s3c2410_gpio_pullup(S3C2410_GPH(3), 1); | 72 | s3c2410_gpio_pullup(S3C2410_GPH(3), 1); |
100 | 73 | ||
101 | #ifdef CONFIG_LEDS_H1940 | ||
102 | led_trigger_register_simple("h1940-bluetooth", &bt_led_trigger); | ||
103 | #endif | ||
104 | 74 | ||
105 | /* disable BT by default */ | 75 | rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH, |
106 | h1940bt_enable(0); | 76 | &h1940bt_rfkill_ops, NULL); |
77 | if (!rfk) { | ||
78 | ret = -ENOMEM; | ||
79 | goto err_rfk_alloc; | ||
80 | } | ||
81 | |||
82 | rfkill_set_led_trigger_name(rfk, "h1940-bluetooth"); | ||
83 | |||
84 | ret = rfkill_register(rfk); | ||
85 | if (ret) | ||
86 | goto err_rfkill; | ||
87 | |||
88 | platform_set_drvdata(pdev, rfk); | ||
89 | |||
90 | return 0; | ||
107 | 91 | ||
108 | return device_create_file(&pdev->dev, &dev_attr_enable); | 92 | err_rfkill: |
93 | rfkill_destroy(rfk); | ||
94 | err_rfk_alloc: | ||
95 | return ret; | ||
109 | } | 96 | } |
110 | 97 | ||
111 | static int h1940bt_remove(struct platform_device *pdev) | 98 | static int h1940bt_remove(struct platform_device *pdev) |
112 | { | 99 | { |
113 | #ifdef CONFIG_LEDS_H1940 | 100 | struct rfkill *rfk = platform_get_drvdata(pdev); |
114 | led_trigger_unregister_simple(bt_led_trigger); | 101 | |
115 | #endif | 102 | platform_set_drvdata(pdev, NULL); |
103 | |||
104 | if (rfk) { | ||
105 | rfkill_unregister(rfk); | ||
106 | rfkill_destroy(rfk); | ||
107 | } | ||
108 | rfk = NULL; | ||
109 | |||
110 | h1940bt_enable(0); | ||
111 | |||
116 | return 0; | 112 | return 0; |
117 | } | 113 | } |
118 | 114 | ||