Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
170 | giacomo | 1 | //SHARK version by Giacomo Guidi <giacomo@gandalf.sssup.it> |
2 | |||
3 | #define __NO_VERSION__ 1 |
||
4 | |||
5 | #include <sys/types.h> |
||
6 | #include "drivers/compbttv.h" |
||
7 | #include <asm/bitops.h> |
||
8 | |||
9 | #include "drivers/bt848.h" |
||
10 | #include "drivers/gpio.h" |
||
11 | |||
12 | #define printk cprintf |
||
13 | /*********************/ |
||
14 | /* gpio_adapter ctor */ |
||
15 | void init_gpio_adapter ( struct gpio_adapter *gpio ) |
||
16 | { |
||
17 | //ignore overlapped fields...they are configured elsewhere |
||
18 | |||
19 | gpio->state = 0; |
||
20 | gpio->sync_bits = 0; |
||
21 | gpio->async_mask = ~0; //assign everything to async control |
||
22 | gpio->async_bits = 0; |
||
23 | |||
24 | init_request_queue(&(gpio->request_queue)); |
||
25 | init_request_queue(&(gpio->free_queue)); |
||
26 | |||
27 | gpio->private_data = NULL; |
||
28 | } |
||
29 | |||
30 | /********************************************************************/ |
||
31 | /* async bit methods...restricted to the bits allowed in async mode */ |
||
32 | static void gpio_apply_bits ( struct gpio_adapter * ); |
||
33 | |||
34 | void gpio_set ( struct gpio_adapter *gpio, __u32 data ) |
||
35 | { |
||
36 | //printk("gpio: set called with %08lX\n",(unsigned long)data); |
||
37 | gpio->async_bits = data & gpio->async_mask; |
||
38 | //printk("gpio: set to: %06lX\n",(long)(gpio->async_bits|gpio->sync_bits)); |
||
39 | gpio_apply_bits(gpio); |
||
40 | } |
||
41 | |||
42 | void gpio_and ( struct gpio_adapter *gpio, __u32 data ) |
||
43 | { |
||
44 | //printk("gpio: and called with &=%08lX\n",(unsigned long)data); |
||
45 | gpio->async_bits &= data; // disallowed bits are already zero... |
||
46 | //printk("gpio: and to: %06lX\n",(long)(gpio->async_bits|gpio->sync_bits)); |
||
47 | gpio_apply_bits(gpio); |
||
48 | } |
||
49 | |||
50 | void gpio_or ( struct gpio_adapter *gpio, __u32 data ) |
||
51 | { |
||
52 | //printk("gpio: or called with |=%08lX\n",(unsigned long)data); |
||
53 | gpio->async_bits |= data & gpio->async_mask; |
||
54 | //printk("gpio: or to: %06lX\n",(long)(gpio->async_bits|gpio->sync_bits)); |
||
55 | gpio_apply_bits(gpio); |
||
56 | } |
||
57 | |||
58 | /* placed here to (hopefully) allow near jumps (smaller/faster) */ |
||
59 | static void gpio_apply_bits ( struct gpio_adapter *gpio ) |
||
60 | { |
||
61 | if (!test_bit(GPIO_HW_LOCKED,&(gpio->state))) { |
||
62 | __u32 value = gpio->sync_bits|gpio->async_bits; |
||
63 | *(__u32 *)(gpio->bt848_mem+BT848_GPIO_DATA) = value; |
||
64 | //printk("gpio: %06lX\n",(long)value); |
||
65 | //printk("gpio: out_en = %06lX\n",(long)readl(gpio->bt848_mem+BT848_GPIO_OUT_EN)); |
||
66 | } else { |
||
67 | // can't update...leave it for task holding hardware lock |
||
68 | set_bit(GPIO_ASYNC_MOD,&(gpio->state)); |
||
69 | // yes, that's correct...the sync task must up our async_lock |
||
70 | // this prevents the next async write until this one hits the hardware |
||
71 | } |
||
72 | |||
73 | } |
||
74 | |||
75 | void gpio_andor ( struct gpio_adapter *gpio, __u32 and_data, __u32 or_data ) |
||
76 | { |
||
77 | //printk("gpio: andor called with &=%08lX and |=%08lX\n",(unsigned long)and_data,(unsigned long)or_data); |
||
78 | gpio->async_bits &= and_data; |
||
79 | gpio->async_bits |= or_data & gpio->async_mask; |
||
80 | //printk("gpio: aor to: %06lX\n",(long)(gpio->async_bits|gpio->sync_bits)); |
||
81 | gpio_apply_bits(gpio); |
||
82 | } |
||
83 | |||
84 | /***********************/ |
||
85 | /* synchronous methods */ |
||
86 | static inline void gpio_sync_write( struct gpio_adapter *gpio, |
||
87 | __u32 sync_bits, |
||
88 | __u32 *async_bits ) |
||
89 | { |
||
90 | if (test_and_clear_bit(GPIO_ASYNC_MOD,&((gpio)->state))) { |
||
91 | *async_bits = (gpio)->async_bits; |
||
92 | } |
||
93 | *(__u32 *)(gpio->bt848_mem+BT848_GPIO_DATA) = (sync_bits)|(*async_bits); |
||
94 | } |
||
95 | |||
96 | static inline void gpio_sync_acquire_hardware( struct gpio_adapter *gpio ) |
||
97 | { |
||
98 | if (test_and_set_bit(GPIO_HW_LOCKED,&(gpio->state))) |
||
99 | printk("gpio: acquire\n");; |
||
100 | } |
||
101 | |||
102 | static void gpio_sync_release_hardware ( struct gpio_adapter *gpio ) |
||
103 | { |
||
104 | if (test_and_clear_bit(GPIO_ASYNC_MOD,&(gpio->state))) { |
||
105 | //we are responsible for a final update...do it here |
||
106 | *(__u32 *)(gpio->bt848_mem+BT848_GPIO_DATA) = gpio->sync_bits|gpio->async_bits; |
||
107 | } |
||
108 | /* must have the hardware to release it */ |
||
109 | if (!test_and_clear_bit(GPIO_HW_LOCKED,&(gpio->state))) { |
||
110 | printk("gpio: release\n");; |
||
111 | } |
||
112 | } |
||
113 | |||
114 | /* request queue access */ |
||
115 | void gpio_commit_request( struct gpio_adapter *gpio, |
||
116 | struct gpio_request *request ) |
||
117 | { |
||
118 | list_add_tail(&(request->list),&(gpio->request_queue.list)); |
||
119 | } |
||
120 | |||
121 | void gpio_commit_transaction( struct gpio_adapter *gpio, |
||
122 | struct list_head *list ) |
||
123 | { |
||
124 | list_splice(list,gpio->request_queue.list.prev); |
||
125 | } |
||
126 |