diff options
| -rw-r--r-- | arch/arm/mach-s3c2410/Kconfig | 8 | ||||
| -rw-r--r-- | arch/arm/mach-s3c2410/Makefile | 3 | ||||
| -rw-r--r-- | arch/arm/mach-s3c2410/h1940-bluetooth.c | 88 |
3 files changed, 52 insertions, 47 deletions
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 3d4e9da3fa52..dd1fcc7e6708 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig | |||
| @@ -81,6 +81,14 @@ config ARCH_H1940 | |||
| 81 | help | 81 | help |
| 82 | Say Y here if you are using the HP IPAQ H1940 | 82 | Say Y here if you are using the HP IPAQ H1940 |
| 83 | 83 | ||
| 84 | config H1940BT | ||
| 85 | tristate "Control the state of H1940 bluetooth chip" | ||
| 86 | depends on ARCH_H1940 | ||
| 87 | select RFKILL | ||
| 88 | help | ||
| 89 | This is a simple driver that is able to control | ||
| 90 | the state of built in bluetooth chip on h1940. | ||
| 91 | |||
| 84 | config PM_H1940 | 92 | config PM_H1940 |
| 85 | bool | 93 | bool |
| 86 | help | 94 | help |
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 2ab5ba4b266f..0d468e96e83e 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile | |||
| @@ -21,7 +21,8 @@ obj-$(CONFIG_S3C2410_PLLTABLE) += pll.o | |||
| 21 | # Machine support | 21 | # Machine support |
| 22 | 22 | ||
| 23 | obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o | 23 | obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o |
| 24 | obj-$(CONFIG_ARCH_H1940) += mach-h1940.o h1940-bluetooth.o | 24 | obj-$(CONFIG_ARCH_H1940) += mach-h1940.o |
| 25 | obj-$(CONFIG_H1940BT) += h1940-bluetooth.o | ||
| 25 | obj-$(CONFIG_PM_H1940) += pm-h1940.o | 26 | obj-$(CONFIG_PM_H1940) += pm-h1940.o |
| 26 | obj-$(CONFIG_MACH_N30) += mach-n30.o | 27 | obj-$(CONFIG_MACH_N30) += mach-n30.o |
| 27 | obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o | 28 | obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o |
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 | ||
