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 help Say Y here if you are using the HP IPAQ H1940 +config H1940BT + tristate "Control the state of H1940 bluetooth chip" + depends on ARCH_H1940 + select RFKILL + help + This is a simple driver that is able to control + the state of built in bluetooth chip on h1940. + config PM_H1940 bool 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 # Machine support obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o -obj-$(CONFIG_ARCH_H1940) += mach-h1940.o h1940-bluetooth.o +obj-$(CONFIG_ARCH_H1940) += mach-h1940.o +obj-$(CONFIG_H1940BT) += h1940-bluetooth.o obj-$(CONFIG_PM_H1940) += pm-h1940.o obj-$(CONFIG_MACH_N30) += mach-n30.o 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 @@ #include #include #include +#include #include #include @@ -24,21 +25,10 @@ #define DRV_NAME "h1940-bt" -#ifdef CONFIG_LEDS_H1940 -DEFINE_LED_TRIGGER(bt_led_trigger); -#endif - -static int state; - /* Bluetooth control */ static void h1940bt_enable(int on) { if (on) { -#ifdef CONFIG_LEDS_H1940 - /* flashing Blue */ - led_trigger_event(bt_led_trigger, LED_HALF); -#endif - /* Power on the chip */ h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER); /* Reset the chip */ @@ -46,48 +36,31 @@ static void h1940bt_enable(int on) s3c2410_gpio_setpin(S3C2410_GPH(1), 1); mdelay(10); s3c2410_gpio_setpin(S3C2410_GPH(1), 0); - - state = 1; } else { -#ifdef CONFIG_LEDS_H1940 - led_trigger_event(bt_led_trigger, 0); -#endif - s3c2410_gpio_setpin(S3C2410_GPH(1), 1); mdelay(10); s3c2410_gpio_setpin(S3C2410_GPH(1), 0); mdelay(10); h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0); - - state = 0; } } -static ssize_t h1940bt_show(struct device *dev, struct device_attribute *attr, char *buf) +static int h1940bt_set_block(void *data, bool blocked) { - return snprintf(buf, PAGE_SIZE, "%d\n", state); + h1940bt_enable(!blocked); + return 0; } -static ssize_t h1940bt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - int new_state; - char *endp; - - new_state = simple_strtoul(buf, &endp, 0); - if (*endp && !isspace(*endp)) - return -EINVAL; - - h1940bt_enable(new_state); - - return count; -} -static DEVICE_ATTR(enable, 0644, - h1940bt_show, - h1940bt_store); +static const struct rfkill_ops h1940bt_rfkill_ops = { + .set_block = h1940bt_set_block, +}; static int __init h1940bt_probe(struct platform_device *pdev) { + struct rfkill *rfk; + int ret = 0; + /* Configures BT serial port GPIOs */ s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); s3c2410_gpio_pullup(S3C2410_GPH(0), 1); @@ -98,21 +71,44 @@ static int __init h1940bt_probe(struct platform_device *pdev) s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); s3c2410_gpio_pullup(S3C2410_GPH(3), 1); -#ifdef CONFIG_LEDS_H1940 - led_trigger_register_simple("h1940-bluetooth", &bt_led_trigger); -#endif - /* disable BT by default */ - h1940bt_enable(0); + rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH, + &h1940bt_rfkill_ops, NULL); + if (!rfk) { + ret = -ENOMEM; + goto err_rfk_alloc; + } - return device_create_file(&pdev->dev, &dev_attr_enable); + rfkill_set_led_trigger_name(rfk, "h1940-bluetooth"); + + ret = rfkill_register(rfk); + if (ret) + goto err_rfkill; + + platform_set_drvdata(pdev, rfk); + + return 0; + +err_rfkill: + rfkill_destroy(rfk); +err_rfk_alloc: + return ret; } static int h1940bt_remove(struct platform_device *pdev) { -#ifdef CONFIG_LEDS_H1940 - led_trigger_unregister_simple(bt_led_trigger); -#endif + struct rfkill *rfk = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + + if (rfk) { + rfkill_unregister(rfk); + rfkill_destroy(rfk); + } + rfk = NULL; + + h1940bt_enable(0); + return 0; } diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index c425eefb9f89..4c79ac8a6c33 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -248,7 +248,7 @@ static int chip0_map[] = { 1 }; static int chip1_map[] = { 2 }; static int chip2_map[] = { 3 }; -static struct mtd_partition bast_default_nand_part[] = { +static struct mtd_partition __initdata bast_default_nand_part[] = { [0] = { .name = "Boot Agent", .size = SZ_16K, @@ -274,7 +274,7 @@ static struct mtd_partition bast_default_nand_part[] = { * socket. */ -static struct s3c2410_nand_set bast_nand_sets[] = { +static struct s3c2410_nand_set __initdata bast_nand_sets[] = { [0] = { .name = "SmartMedia", .nr_chips = 1, @@ -324,7 +324,7 @@ static void bast_nand_select(struct s3c2410_nand_set *set, int slot) __raw_writeb(tmp, BAST_VA_CTRL2); } -static struct s3c2410_platform_nand bast_nand_info = { +static struct s3c2410_platform_nand __initdata bast_nand_info = { .tacls = 30, .twrph0 = 60, .twrph1 = 60, @@ -631,7 +631,6 @@ static void __init bast_map_io(void) s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); - s3c_device_nand.dev.platform_data = &bast_nand_info; s3c_device_hwmon.dev.platform_data = &bast_hwmon_info; s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); @@ -645,6 +644,7 @@ static void __init bast_init(void) sysdev_register(&bast_pm_sysdev); s3c_i2c0_set_platdata(&bast_i2c_info); + s3c_nand_set_platdata(&bast_nand_info); s3c24xx_fb_set_platdata(&bast_fb_info); platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index d9cd5ddecf4a..49053254c98d 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -21,6 +21,11 @@ #include #include #include +#include +#include +#include