]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
h63xx: bluetooth support
authorMika Laitio <lamikr@pilppa.org>
Mon, 19 Jan 2009 23:13:58 +0000 (01:13 +0200)
committerMika Laitio <lamikr@pilppa.org>
Mon, 19 Jan 2009 23:13:58 +0000 (01:13 +0200)
arch/arm/configs/omap_h63xx_defconfig
arch/arm/mach-omap1/board-h6300.c
drivers/bluetooth/Kconfig
drivers/bluetooth/Makefile
drivers/bluetooth/omap/Makefile [new file with mode: 0644]
drivers/bluetooth/omap/h6300_bt_brf6100.c [new file with mode: 0644]
drivers/bluetooth/omap/h6300_bt_led.c [new file with mode: 0644]
drivers/bluetooth/omap/h6300_bt_led.h [new file with mode: 0644]
include/asm-arm/arch-omap/h6300_uart_info.h [new file with mode: 0644]
include/asm-arm/arch-omap/omap_serial.h [new file with mode: 0644]

index 20d37c41b10344f9f806789c58593682f8de3158..2bc595da2a8874f4aa224abaeca00da5e22fe85b 100644 (file)
@@ -480,6 +480,7 @@ CONFIG_BT_HCIUART_BCSP=y
 # CONFIG_BT_HCIBTUART is not set
 # CONFIG_BT_HCIBRF6150 is not set
 CONFIG_BT_HCIVHCI=m
+CONFIG_BT_H6300=m
 # CONFIG_IEEE80211 is not set
 
 #
@@ -907,6 +908,7 @@ CONFIG_I2C_OMAP=m
 # CONFIG_SENSORS_DS1374 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+CONFIG_PCA9535=y
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
index 2bcc34f9e6c9c08e06377d73172cad4aec75a56e..09f14777f1f4d38db23467e58e23bc320a50ab03 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/arch/usb.h>
 #include <asm/arch/keypad.h>
 #include <asm/arch/common.h>
+#include <asm/arch/h6300_uart_info.h>
 
 #define _h6300_KEY_CALENDAR    67      // xmodmap 75 aka F9
 #define _H6300_KEY_TELEPHONE   68      // xmodmap 76 aka F10
@@ -104,6 +105,24 @@ static struct platform_device h6300_kp_device = {
        .resource       = h6300_kp_resources,
 };
 
+/*
+ * Bluetooth - Relies on h6300_bt module,
+ * so make the calls indirectly through pointers. Requires that the
+ * h6300_bt bluetooth module be loaded before any attempt to use
+ * bluetooth (obviously).
+ */
+static struct platform_omap_serial_funcs h6300_omap_platform__uart_bt_funcs = {
+       .configure      = NULL,
+       .set_txrx       = NULL,
+       .get_txrx       = NULL,
+};
+
+struct platform_device btuart_device = {
+       .name   = "h6300_bt",
+       .id     = 1,
+};
+EXPORT_SYMBOL(btuart_device);
+
 static struct platform_device *h6300_devices[] __initdata = {
        &h6300_lcd_device,
        &h6300_kp_device,
@@ -169,6 +188,8 @@ static void __init h6300_init(void)
 static void __init h6300_map_io(void)
 {
        omap1_map_common_io();
+
+       h63xx_uart_bt_device.dev.platform_data  = &h6300_omap_platform__uart_bt_funcs;
 }
 
 MACHINE_START(OMAP_H6300, "HP iPAQ h6300")
index 9abcd6206ac321c9306854f6ced36008ffceb911..e05424c6749ea09083d314db0edb0208a9494605 100644 (file)
@@ -166,6 +166,16 @@ config BT_HCIVHCI
 
          Say Y here to compile support for virtual HCI devices into the
          kernel or say M to compile it as module (hci_vhci).
+         
+config BT_H6300
+       tristate "H6300 BRF6100 BT DRIVER"
+       help
+         Bluetooth H6300 BRF6100 driver.
+         This driver provides the firmware loading mechanism for the BRF6100
+         bt hardware in iPAQ h6300.
+
+         Say Y here to compile support for BRF6100 BT devices into the
+         kernel or say M to compile it as module (h6300_BT).     
 
 endmenu
 
index 18aa038db1367d655d98b810c3bc8ba22f8862cb..8f9df8253424b23c990247e8f802384d70bf867d 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_BT_HCIBT3C)      += bt3c_cs.o
 obj-$(CONFIG_BT_HCIBLUECARD)   += bluecard_cs.o
 obj-$(CONFIG_BT_HCIBTUART)     += btuart_cs.o
 obj-$(CONFIG_BT_HCIBRF6150)    += brf6150.o
+obj-$(CONFIG_BT_H6300)         += omap/
 
 hci_uart-y                             := hci_ldisc.o
 hci_uart-$(CONFIG_BT_HCIUART_H4)       += hci_h4.o
diff --git a/drivers/bluetooth/omap/Makefile b/drivers/bluetooth/omap/Makefile
new file mode 100644 (file)
index 0000000..5465d7f
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the Linux iPAQ H6300 BRF6100 Bluetooth device drivers.
+#
+
+h6300_bt-objs                          := h6300_bt_led.o h6300_bt_brf6100.o
+obj-$(CONFIG_BT_H6300)         += h6300_bt.o
diff --git a/drivers/bluetooth/omap/h6300_bt_brf6100.c b/drivers/bluetooth/omap/h6300_bt_brf6100.c
new file mode 100644 (file)
index 0000000..3c9b564
--- /dev/null
@@ -0,0 +1,154 @@
+/* 
+ * Bluetooth interface driver for TI BRF6100 on h6300
+ * 
+ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi>
+ * Ideas taken from the brf6150 bt driver made by Todd Blumer for the pxa hx4700.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/gpio.h>
+
+#include <asm/arch/h6300_uart_info.h>
+#include "h6300_bt_led.h"
+
+static void
+h6300_bt_configure(struct uart_omap_port *up, int enable)
+{
+       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_configure() started, enable = %d\n", enable);
+       
+       // printk( KERN_NOTICE "h6300 configure bluetooth: %d\n", enable );
+       if (enable == 0) {
+               omap_set_gpio_dataout(GPIO_N_BT_RST, 1);        // turn off gpio, note 1 == off for negative gpios
+               mdelay(5);
+               h6300_clear_led(INDEX_BT_LED);
+       }
+       else if (enable == 1) {
+               omap_set_gpio_dataout(GPIO_N_BT_RST, 1);        // turn on gpio, note 0 == on for negative gpios
+               mdelay(5);                              
+       }
+       else if (enable == 2) {
+               /*
+                * BRF6150's RTS goes low when firmware is ready
+                * so check for CTS=1 (nCTS=0 -> CTS=1). Typical 150ms
+                */
+/*             
+               int tries = 0; 
+               do 
+               {
+                       mdelay(10);
+               } 
+               while ((BTMSR & MSR_CTS) == 0 && tries++ < 50);
+*/                             
+               h6300_set_led(INDEX_BT_LED, 16, 16);
+       }
+       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_configure() done\n");
+}
+
+static void
+h6300_bt_set_txrx(struct uart_omap_port *up, int txrx)
+{
+       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_set_txrx(), txrx = %d done\n", txrx);
+       /* do nothing */
+}
+
+static int
+h6300_bt_get_txrx(struct uart_omap_port *up)
+{
+       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_get_txrx() done\n");
+       /* do nothing */
+       return 0;
+}
+
+static int
+h6300_bt_probe(struct platform_device *pdev)
+{
+       struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
+
+       omap_request_gpio(GPIO_BT_PWR_EN);              // ask bt_power_en gpio, remember to release in remove_function
+       omap_set_gpio_direction(GPIO_BT_PWR_EN, 1);     // set gpio direction to be output
+       omap_set_gpio_dataout(GPIO_BT_PWR_EN, 1);       // turn on gpio
+
+       mdelay(200);
+
+       omap_request_gpio(GPIO_N_BT_RST);               // ask bt_reset gpio, remember to release in remove_function
+       omap_set_gpio_direction(GPIO_N_BT_RST, 1);      // set gpio direction to be output
+       omap_set_gpio_dataout(GPIO_N_BT_RST, 0);        // turn on gpio, note 0 == on for negative gpios
+       
+       /* configure bluetooth UART */
+       //h6300_gpio_mode(GPIO_NR_H6300_BT_RXD_MD);
+       //h6300_gpio_mode(GPIO_NR_H6300_BT_TXD_MD);
+       //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_CTS_MD);
+       //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_RTS_MD);
+
+       funcs->configure        = h6300_bt_configure;
+       funcs->set_txrx         = h6300_bt_set_txrx;
+       funcs->get_txrx         = h6300_bt_get_txrx;
+
+       /* Make sure the LED is off */
+       h6300_clear_led(INDEX_BT_LED);
+       
+       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_probe() done\n");       
+
+       return 0;
+}
+
+static int
+h6300_bt_remove(struct platform_device *pdev)
+{
+       struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
+       
+       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_remove() started\n");   
+       
+       omap_free_gpio(GPIO_BT_PWR_EN);
+       omap_free_gpio(GPIO_N_BT_RST);
+
+       funcs->configure        = NULL;
+       funcs->set_txrx         = NULL;
+       funcs->get_txrx         = NULL;
+
+       /* Make sure the LED is off */
+       h6300_clear_led(INDEX_BT_LED);
+       
+       printk(KERN_NOTICE "h6300_bt_brf6100.c, h6300_bt_remove() done\n");
+
+       return 0;
+}
+
+static struct platform_driver bt_driver = {
+       .probe    = h6300_bt_probe,
+       .remove   = h6300_bt_remove,
+       .driver = {
+               .name = "h6300_bt",
+       },
+};
+
+static int __init
+h6300_bt_init(void)
+{
+       printk(KERN_NOTICE "h6300 Bluetooth Driver init()\n");
+       return platform_driver_register(&bt_driver);
+}
+
+static void __exit
+h6300_bt_exit(void)
+{
+       printk(KERN_NOTICE "h6300 Bluetooth Driver exit()\n");
+       platform_driver_unregister(&bt_driver);
+}
+
+module_init(h6300_bt_init);
+module_exit(h6300_bt_exit);
+
+MODULE_AUTHOR("Mika Laitio, <lamikr@cc.jyu.fi>");
+MODULE_DESCRIPTION("iPAQ h6300 BRF6100 Bluetooth driver.");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/bluetooth/omap/h6300_bt_led.c b/drivers/bluetooth/omap/h6300_bt_led.c
new file mode 100644 (file)
index 0000000..18458c3
--- /dev/null
@@ -0,0 +1,41 @@
+/* 
+ * Bluetooth interface driver helper for controlling bluetooth leds available in iPAQ h6300.
+ * 
+ * Copyright (C) 2005 Mika Laitio  <lamikr@cc.jyu.fi>
+ * Ideas from the brf6150 bt driver made by Todd Blumer for the pxa hx4700.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/gpio.h>
+
+/* 
+ * Low level access for disabling h6300 bt led.
+ *
+ * TODO: implement for h6300 
+ */
+void h6300_clear_led(int led_num)
+{
+       printk(KERN_NOTICE "h6300_bt_led.c h6300_clear_led() done\n");
+       //hx4700_set_led(led_num, 0, 16);
+}
+EXPORT_SYMBOL(h6300_clear_led);
+
+/* 
+ * Low level access for setting up the bt led.
+ *
+ * TODO: implement for h6300 
+ */
+void h6300_set_led(int led_num, int duty_time, int cycle_time)
+{
+       printk(KERN_NOTICE "h6300_bt_led.c h6300_set_led() done\n");
+}
+EXPORT_SYMBOL(h6300_set_led);
diff --git a/drivers/bluetooth/omap/h6300_bt_led.h b/drivers/bluetooth/omap/h6300_bt_led.h
new file mode 100644 (file)
index 0000000..23a7174
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef H6300_BT_LED_H_
+#define H6300_BT_LED_H_
+
+#define INDEX_BT_LED   2
+
+void h6300_clear_led(int led_num);
+void h6300_set_led(int led_num, int duty_time, int cycle_time);
+
+#endif /*H6300_BT_LED_H_*/
diff --git a/include/asm-arm/arch-omap/h6300_uart_info.h b/include/asm-arm/arch-omap/h6300_uart_info.h
new file mode 100644 (file)
index 0000000..7c36104
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Support file for calling h6300 uart configuration functions.
+ * Used at least by h6300_bt driver.
+ * 
+ * Copyright (c) 2005 SDG Systems, LLC
+ * 2005-03-29   Todd Blumer     Converted  basic structure to support hx4700
+ * 2005-10-03   Mika Laitio (lamikr@cc.jyu.fi) Reorganized for the iPAQ h6300 bt driver.
+ */
+
+#ifndef _H6300_UART_INFO_H
+#define _H6300_UART_INFO_H
+
+#include "omap_serial.h"
+
+#define GPIO_BT_PWR_EN 3
+#define GPIO_N_BT_RST 9
+
+#define GPIO_I2C_GPRS_RESET 16
+#define GPIO_I2C_MIC_OP_EN 10
+#define GPIO_I2C_SPK_OP_PD 11
+
+#define GPIO_VALUE_OFF 0
+#define GPIO_VALUE_ON  1
+
+#define GPIO_DIR_OUTPUT 1
+
+struct h6300_uart_funcs {
+       void (*configure)( struct uart_omap_port *up, int state);
+       void (*set_txrx)( struct uart_omap_port *up, int txrx);
+       int (*get_txrx)( struct uart_omap_port *up);
+};
+
+#endif
diff --git a/include/asm-arm/arch-omap/omap_serial.h b/include/asm-arm/arch-omap/omap_serial.h
new file mode 100644 (file)
index 0000000..add09dc
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Omap/h6300 serial driver private interface. 
+ * Code originates from the pxa-serial.h available in the handheld org drivers
+ * for iPAQ PXA4700.
+ *
+ * Copyright (c) 2005 SDG Systems, LLC
+ * 2005-03-29   Todd Blumer     Converted  basic structure to support hx4700
+ * 2005-10-03   Mika Laitio (lamikr@cc.jyu.fi) Reorganized for the iPAQ h6300 bt driver.
+ */
+#ifndef _OMAP_SERIAL_H
+#define _OMAP_SERIAL_H
+
+#define OMAP_SERIAL_TX 1
+#define OMAP_SERIAL_RX 2
+
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+
+struct platform_omap_serial_funcs;
+
+struct uart_omap_port {
+       struct uart_port                        port;
+       unsigned char                           ier;
+       unsigned char                           lcr;
+       unsigned char                           mcr;
+       unsigned int                            lsr_break_flag;
+       unsigned int                            cken;
+       char                                    *name;
+       struct platform_omap_serial_funcs       *pf;
+};
+
+/* A pointer to such a structure can be contained in the platform_data
+ * field of every PXA UART platform_device. If the field is NULL, the
+ * serial port works as usual.
+ *
+ * For the sake of simplicity/performance no one of the function pointers
+ * in the structure below can be NULL.
+ */
+struct platform_omap_serial_funcs {
+       /* Platform-specific function to initialize whatever is connected
+         to this serial port... enable=1 -> enable transceiver,
+         0 -> disable transceiver. */
+       void (*configure) (struct uart_omap_port *up, int enable);
+        /* Platform-specific function to enable or disable the individual
+           transmitter/receiver submodules. On transceivers without echo
+           cancellation (e.g. SIR) transmitter always has priority, e.g.
+           if both bits are set, only the transmitter is enabled. */
+        void (*set_txrx) (struct uart_omap_port *up, int txrx);
+       /* Get the current state of tx/rx (see bitflags above) */
+       int (*get_txrx) (struct uart_omap_port *up);
+};
+
+/*
+ * The variables below are located in arch/arm/mach-omap/board_h6300.c
+ * Machine-specific code may want to put a pointer to a static
+ * platform_pxa_serial_funcs structure in the dev.platform_data
+ * field of the respective port device.
+ */
+extern struct platform_device btuart_device;
+
+#endif