sync hh.org
[hh.org.git] / arch / arm / mach-sa1100 / h3600_asic_bluetooth.c
blobb60ecaec6a2aa57e0040bf9ce24fb7e0d0d62651
1 /*
2 * Driver interface to the ASIC Complasion chip on the iPAQ H3800
4 * Copyright 2001 Compaq Computer Corporation.
6 * Use consistent with the GNU GPL is permitted,
7 * provided that this copyright notice is
8 * preserved in its entirety in all copies and derived works.
10 * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
11 * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
12 * FITNESS FOR ANY PARTICULAR PURPOSE.
14 * Author: Andrew Christian
15 * <Andrew.Christian@compaq.com>
16 * October 2001
18 * Restrutured June 2002
21 #include <linux/module.h>
22 #include <linux/version.h>
24 #include <linux/init.h>
25 #include <linux/fs.h>
26 #include <linux/interrupt.h>
27 #include <linux/sched.h>
28 #include <linux/pm.h>
29 #include <linux/sysctl.h>
30 #include <linux/proc_fs.h>
31 #include <linux/mtd/mtd.h>
32 #include <linux/ctype.h>
33 #include <linux/spi/spi.h>
34 #include <linux/delay.h>
35 #include <linux/serial.h> /* For bluetooth */
37 #include <asm/irq.h>
38 #include <asm/uaccess.h> /* for copy to/from user space */
39 #include <asm/arch/hardware.h>
40 #include <asm/arch-sa1100/h3600_hal.h>
41 #include <asm/arch-sa1100/h3600_asic.h>
42 #include <asm/arch-sa1100/serial_h3800.h>
44 #include "h3600_asic_io.h"
45 #include "h3600_asic_core.h"
47 /***********************************************************************************
48 * Bluetooth
50 * Resources used:
51 * Shared resources:
53 ***********************************************************************************/
55 struct ipaq_asic2_bluetooth {
56 int line; // Serial port line
57 unsigned long shared;
60 static struct ipaq_asic2_bluetooth g_bluedev;
62 static void ipaq_asic2_bluetooth_up( struct ipaq_asic2_bluetooth *dev )
64 H3800_ASIC2_INTR_MaskAndFlag &= ~ASIC2_INTMASK_UART_0;
66 H3800_ASIC2_UART_0_RSR = 1; // Reset the UART
67 H3800_ASIC2_UART_0_RSR = 0;
69 H3800_ASIC2_CLOCK_Enable =
70 (H3800_ASIC2_CLOCK_Enable & ~ASIC2_CLOCK_UART_0_MASK) | ASIC2_CLOCK_SLOW_UART_0;
71 ipaq_asic2_shared_add( &dev->shared, ASIC_SHARED_CLOCK_EX1 );
73 // H3600.c has already taken care of sending the 3.6864 MHz clock to the UART (TUCR)
74 // but we're paranoid...
75 GPDR |= GPIO_H3800_CLK_OUT;
76 GAFR |= GPIO_H3800_CLK_OUT;
78 TUCR = TUCR_3_6864MHzA;
80 // Set up the TXD & RXD of the UART to normal operation
81 H3800_ASIC2_GPIODIR &= ~GPIO2_UART0_TXD_ENABLE;
82 H3800_ASIC2_GPIOPIOD |= GPIO2_UART0_TXD_ENABLE;
84 // More black magic
85 H3800_ASIC2_KPIODIR &= ~KPIO_UART_MAGIC;
86 H3800_ASIC2_KPIOPIOD |= KPIO_UART_MAGIC;
89 static void ipaq_asic2_bluetooth_down( struct ipaq_asic2_bluetooth *dev )
91 H3800_ASIC2_INTR_MaskAndFlag |= ASIC2_INTMASK_UART_0;
92 ipaq_asic2_shared_release( &dev->shared, ASIC_SHARED_CLOCK_EX1 );
95 int ipaq_asic2_bluetooth_suspend( void )
97 ipaq_asic2_bluetooth_down( &g_bluedev );
98 return 0;
101 void ipaq_asic2_bluetooth_resume( void )
103 ipaq_asic2_bluetooth_up( &g_bluedev );
106 static void serial_fn_pm( struct uart_port *port, u_int state, u_int oldstate )
108 if (0) printk("%s: %p %d %d\n", __FUNCTION__, port, state, oldstate);
111 static int serial_fn_open( struct uart_port *port, struct uart_info *info )
113 if (0) printk("%s: %p %p\n", __FUNCTION__, port, info);
114 MOD_INC_USE_COUNT;
116 H3800_ASIC1_GPIO_OUT |= GPIO1_BT_PWR_ON;
117 ipaq_asic2_led_blink(BLUE_LED,1,7,1);
118 return 0;
121 static void serial_fn_close( struct uart_port *port, struct uart_info *info )
123 if (0) printk("%s: %p %p\n", __FUNCTION__, port, info);
124 ipaq_asic2_led_off(BLUE_LED);
125 H3800_ASIC1_GPIO_OUT &= ~GPIO1_BT_PWR_ON;
127 MOD_DEC_USE_COUNT;
130 static struct serial_h3800_fns serial_fns = {
131 pm : serial_fn_pm,
132 open : serial_fn_open,
133 close : serial_fn_close
136 int ipaq_asic2_bluetooth_init( void )
138 struct serial_struct ipaq_asic2_serial_struct;
140 ipaq_asic2_bluetooth_up( &g_bluedev );
142 g_bluedev.line = register_serial(&h3800_serial_req);
143 if ( g_bluedev.line < 0 ) {
144 printk("%s: register serial failed\n", __FUNCTION__);
145 return g_bluedev.line;
148 return 0;
151 void ipaq_asic2_bluetooth_cleanup( void )
153 printk("%s: %d\n", __FUNCTION__, g_bluedev.line);
154 unregister_serial_h3800( g_bluedev.line );
155 ipaq_asic2_bluetooth_down( &g_bluedev );
158 extern struct device_driver ipaq_asic2_bluetooth_device_driver = {
159 .name = "asic2 bluetooth",
160 .probe = ipaq_asic2_bluetooth_init,
161 .shutdown = ipaq_asic2_bluetooth_cleanup,
162 .suspend = ipaq_asic2_bluetooth_suspend,
163 .resume = ipaq_asic2_bluetooth_resume
165 EXPORT_SYMBOL(ipaq_asic2_bluetooth_device_driver);