LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
d_bt.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 
22 #ifndef PCASM
23 #include <asm/types.h>
24 #endif
25 
26 #define HW_ID_SUPPORT
27 
28 #include "../../lms2012/source/lms2012.h"
29 #include "../../lms2012/source/am1808.h"
30 
31 int Hw = 0;
32 
33 #define MODULE_NAME "bluetooth_module"
34 #define DEVICE1_NAME BT_DEVICE
35 #define DEVICE2_NAME UPDATE_DEVICE
36 
37 static int ModuleInit(void);
38 static void ModuleExit(void);
39 
40 #define __USE_POSIX
41 
42 #include <linux/kernel.h>
43 #include <linux/fs.h>
44 
45 #include <linux/sched.h>
46 
47 
48 #ifndef PCASM
49 #include <linux/hrtimer.h>
50 
51 #include <linux/mm.h>
52 #include <linux/hrtimer.h>
53 
54 #include <linux/init.h>
55 #include <linux/uaccess.h>
56 #include <linux/debugfs.h>
57 
58 #include <linux/ioport.h>
59 #include <asm/gpio.h>
60 #include <asm/io.h>
61 #include <linux/module.h>
62 #include <linux/miscdevice.h>
63 #include <asm/uaccess.h>
64 
65 MODULE_LICENSE("GPL");
66 MODULE_AUTHOR("The LEGO Group");
69 
70 module_init(ModuleInit);
71 module_exit(ModuleExit);
72 
73 #else
74 // Keep Eclipse happy
75 #endif
76 
77 
78 enum
79 {
80  SET = 0,
81  CLEAR = 1,
82  HIIMP = 2
83 };
84 
86 {
91 };
92 
93 
95 {
96  { GP5_7 , NULL, 0 }, // CTS_PIC
97  { GP4_14 , NULL, 0 }, // PIC_RST
98  { GP3_3 , NULL, 0 }, // PIC_EN
99 };
100 
101 
103 {
104  { GP5_7 , NULL, 0 }, // CTS_PIC
105  { GP4_14 , NULL, 0 }, // PIC_RST
106  { GP3_3 , NULL, 0 }, // PIC_EN
107 };
108 
109 
111 {
112  { GP5_7 , NULL, 0 }, // CTS_PIC
113  { GP4_14 , NULL, 0 }, // PIC_RST
114  { GP3_3 , NULL, 0 }, // PIC_EN
115 };
116 
117 
119 {
120  [FINAL] = (INPIN*)&FINAL_BluetoothPin[0], // FINAL platform
121  [FINALB] = (INPIN*)&FINALB_BluetoothPin[0], // FINALB platform
122  [EP2] = (INPIN*)&EP2_BluetoothPin[0], // EP2 platform
123 };
124 
125 
126 static void __iomem *GpioBase;
127 static UBYTE *pLocalRam;
128 
129 void SetGpio(int Pin)
130 {
131  int Tmp = 0;
132  void __iomem *Reg;
133 
134  while ((MuxRegMap[Tmp].Pin != -1) && (MuxRegMap[Tmp].Pin != Pin))
135  {
136  Tmp++;
137  }
138  if (MuxRegMap[Tmp].Pin == Pin)
139  {
140  Reg = da8xx_syscfg0_base + 0x120 + (MuxRegMap[Tmp].MuxReg << 2);
141 
142  *(u32*)Reg &= MuxRegMap[Tmp].Mask;
143  *(u32*)Reg |= MuxRegMap[Tmp].Mode;
144 
145  if (Pin < NO_OF_GPIOS)
146  {
147  #ifdef DEBUG
148  printk(" GP%d_%-2d 0x%08X and 0x%08X or 0x%08X\n",(Pin >> 4),(Pin & 0x0F),(u32)Reg, MuxRegMap[Tmp].Mask, MuxRegMap[Tmp].Mode);
149  #endif
150  }
151  else
152  {
153  #ifdef DEBUG
154  printk(" OUTPUT FUNCTION 0x%08X and 0x%08X or 0x%08X\n",(u32)Reg, MuxRegMap[Tmp].Mask, MuxRegMap[Tmp].Mode);
155  #endif
156  }
157  }
158  else
159  {
160  printk(" GP%d_%-2d Not found (Const no. %d, Tmp = %d)\n",(Pin >> 4),(Pin & 0x0F), Pin, Tmp);
161  }
162 }
163 
164 
165 void InitGpio(void)
166 {
167  int Pin;
168 
169  REGUnlock;
170 
171  for (Pin = 0; Pin < BLUETOOTH_PINS; Pin++)
172  {
173  pBluetoothPin[Hw][Pin].pGpio = (struct gpio_controller *__iomem)(GpioBase + ((pBluetoothPin[Hw][Pin].Pin >> 5) * 0x28) + 0x10);
174  pBluetoothPin[Hw][Pin].Mask = (1 << (pBluetoothPin[Hw][Pin].Pin & 0x1F));
175 
176  SetGpio(pBluetoothPin[Hw][Pin].Pin);
177  }
178 
179  REGLock;
180 }
181 
182 
183 #define BtFloat(pin) {\
184  (*pBluetoothPin[Hw][pin].pGpio).dir |= pBluetoothPin[Hw][pin].Mask;\
185  }
186 
187 #define BtRead(pin) ((*pBluetoothPin[Hw][pin].pGpio).in_data & pBluetoothPin[Hw][pin].Mask)
188 
189 #define BtHigh(pin) {\
190  (*pBluetoothPin[Hw][pin].pGpio).set_data = pBluetoothPin[Hw][pin].Mask;\
191  (*pBluetoothPin[Hw][pin].pGpio).dir &= ~pBluetoothPin[Hw][pin].Mask;\
192  }
193 
194 #define BtLow(pin) {\
195  (*pBluetoothPin[Hw][pin].pGpio).clr_data = pBluetoothPin[Hw][pin].Mask;\
196  (*pBluetoothPin[Hw][pin].pGpio).dir &= ~pBluetoothPin[Hw][pin].Mask;\
197  }
198 
199 
200 
201 // DEVICE1 ********************************************************************
202 
203 
204 static ssize_t Device1Write(struct file *File,const char *Buffer,size_t Count,loff_t *Data)
205 {
206  SBYTE Buf[20];
207  int Lng;
208 
209  Lng = Count;
210  copy_from_user(Buf,Buffer,Count);
211 
212  if (SET == (UBYTE)(Buf[0]))
213  {
214  if (BLUETOOTH_PINS > (UBYTE)(Buf[1]))
215  {
216  BtHigh((UBYTE)(Buf[1]));
217  }
218  }
219  else
220  {
221  if (CLEAR == (UBYTE)(Buf[0]))
222  {
223  if (BLUETOOTH_PINS > (UBYTE)(Buf[1]))
224  {
225  BtLow((UBYTE)(Buf[1]));
226  }
227  }
228  else
229  {
230  if (BLUETOOTH_PINS > (UBYTE)(Buf[1]))
231  {
232  BtFloat((UBYTE)(Buf[1]));
233  }
234  }
235  }
236 
237  return (Lng);
238 }
239 
240 
241 static ssize_t Device1Read(struct file *File,char *Buffer,size_t Count,loff_t *Offset)
242 {
243 
244  if (BtRead(CTS_PIC))
245  {
246  Buffer[0] = 1;
247  }
248  else
249  {
250  Buffer[0] = 0;
251  }
252 
253  return(1);
254 }
255 
256 
257 static ssize_t Device2Write(struct file *File,const char *Buffer,size_t Count,loff_t *Data)
258 {
259  *((ULONG*)&(pLocalRam[2])) = 0x5555AAAA;
260  return(1);
261 }
262 
263 
264 static ssize_t Device2Read(struct file *File,char *Buffer,size_t Count,loff_t *Offset)
265 {
266  Buffer[0] = pLocalRam[0];
267  Buffer[1] = pLocalRam[1];
268  return(1);
269 }
270 
271 
272 static const struct file_operations Device1Entries =
273 {
274  .owner = THIS_MODULE,
275  .read = Device1Read,
276  .write = Device1Write
277 };
278 
279 
280 static struct miscdevice Device1 =
281 {
282  MISC_DYNAMIC_MINOR,
283  DEVICE1_NAME,
284  &Device1Entries
285 };
286 
287 
288 static int Device1Init(void)
289 {
290  int Result = -1;
291 
292  Result = misc_register(&Device1);
293  if (Result)
294  {
295  printk(" %s device register failed\n",DEVICE1_NAME);
296  }
297  else
298  {
299  #ifdef DEBUG
300  printk(" %s device register succes\n",DEVICE1_NAME);
301  #endif
302  }
303 
304  return (Result);
305 }
306 
307 
308 static void Device1Exit(void)
309 {
310  misc_deregister(&Device1);
311 #ifdef DEBUG
312  printk(" %s device unregistered\n",DEVICE1_NAME);
313 #endif
314 }
315 
316 
317 /* Device 2 is to handle pirmware update status writing into */
318 /* internal RAM */
319 static const struct file_operations Device2Entries =
320 {
321  .owner = THIS_MODULE,
322  .read = Device2Read,
323  .write = Device2Write
324 };
325 
326 
327 static struct miscdevice Device2 =
328 {
329  MISC_DYNAMIC_MINOR,
330  DEVICE2_NAME,
331  &Device2Entries
332 };
333 
334 
335 static int Device2Init(void)
336 {
337  int Result = -1;
338 
339  Result = misc_register(&Device2);
340  if (Result)
341  {
342  printk(" %s device register failed\n",DEVICE2_NAME);
343  }
344  else
345  {
346  #ifdef DEBUG
347  printk(" %s device register succes\n",DEVICE2_NAME);
348  #endif
349  }
350 
351  return (Result);
352 }
353 
354 
355 static void Device2Exit(void)
356 {
357  misc_deregister(&Device2);
358 #ifdef DEBUG
359  printk(" %s device unregistered\n",DEVICE2_NAME);
360 #endif
361 }
362 
363 
364 // MODULE *********************************************************************
365 
366 
367 #ifndef PCASM
368 module_param (HwId, charp, 0);
369 #endif
370 
371 static int ModuleInit(void)
372 {
373  Hw = HWID;
374 
375  if (Hw < PLATFORM_START)
376  {
377  Hw = PLATFORM_START;
378  }
379  if (Hw > PLATFORM_END)
380  {
381  Hw = PLATFORM_END;
382  }
383 
384  #ifdef DEBUG
385  printk("%s init started\n",MODULE_NAME);
386  #endif
387 
388  /* Local memory for saving the firmware update status */
389  if (request_mem_region(0xFFFF1FFC,0x00000004,MODULE_NAME) >= 0)
390  {
391 
392  pLocalRam = (UBYTE*)ioremap(0xFFFF1FFA,0x00000006);
393 
394  if (pLocalRam != NULL)
395  {
396  #ifdef DEBUG
397  printk("%s Local address mapped\n",MODULE_NAME);
398  #endif
399  }
400  }
401 
402  if (request_mem_region(DA8XX_GPIO_BASE,0xD8,MODULE_NAME) >= 0)
403  {
404  GpioBase = (void*)ioremap(DA8XX_GPIO_BASE,0xD8);
405  if (GpioBase != NULL)
406  {
407  #ifdef DEBUG
408  printk("%s gpio address mapped\n",MODULE_NAME);
409  #endif
410 
411  InitGpio();
412  Device1Init();
413  Device2Init();
414 
415  BtHigh(PIC_RST);
416  BtLow(PIC_EN);
417  BtFloat(CTS_PIC);
418  }
419  }
420  return (0);
421 }
422 
423 
424 static void ModuleExit(void)
425 {
426  #ifdef DEBUG
427  printk("%s exit started\n",MODULE_NAME);
428  #endif
429 
430  BtHigh(PIC_RST);
431  BtLow(PIC_EN);
432 
433  Device1Exit();
434  Device2Exit();
435 
436 }
#define REGLock
Definition: am1808.h:235
signed char SBYTE
Basic Type used to symbolise 8 bit signed values.
Definition: lmstypes.h:33
MRM MuxRegMap[]
Definition: am1808.h:59
module_exit(ModuleExit)
GPIOC pGpio
Definition: am1808.h:225
#define REGUnlock
Definition: am1808.h:230
INPIN EP2_BluetoothPin[BLUETOOTH_PINS]
Definition: d_bt.c:94
Definition: d_bt.c:89
Definition: am1808.h:222
#define EP2
Schematics revision D.
Definition: lms2012.h:99
INPIN FINALB_BluetoothPin[BLUETOOTH_PINS]
Definition: d_bt.c:102
#define FINAL
Final prototype.
Definition: lms2012.h:101
Definition: d_bt.c:81
void InitGpio(void)
Definition: d_bt.c:165
Definition: d_bt.c:87
BluetoothPins
Definition: d_bt.c:85
INPIN * pBluetoothPin[]
Definition: d_bt.c:118
void SetGpio(int Pin)
Definition: d_bt.c:129
Definition: am1808.h:37
#define DEVICE1_NAME
Definition: d_bt.c:34
u16 MuxReg
Definition: am1808.h:53
#define DEVICE2_NAME
Definition: d_bt.c:35
int Hw
Definition: d_bt.c:31
#define BtFloat(pin)
Definition: d_bt.c:183
#define BtLow(pin)
Definition: d_bt.c:194
unsigned int ULONG
Basic Type used to symbolise 32 bit unsigned values.
Definition: lmstypes.h:31
MODULE_LICENSE("GPL")
INPIN FINAL_BluetoothPin[BLUETOOTH_PINS]
Definition: d_bt.c:110
int Pin
Definition: am1808.h:224
#define FINALB
Schematics revision B and C.
Definition: lms2012.h:100
MODULE_DESCRIPTION(MODULE_NAME)
module_param(HwId, charp, 0)
MODULE_AUTHOR("The LEGO Group")
Definition: d_bt.c:80
#define MODULE_NAME
Definition: d_bt.c:33
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
Definition: lmstypes.h:29
#define BtHigh(pin)
Definition: d_bt.c:189
u32 Mask
Definition: am1808.h:226
char Buffer[1024]
Definition: c_wifi.c:102
module_init(ModuleInit)
Definition: d_bt.c:88
#define BtRead(pin)
Definition: d_bt.c:187
uint32_t u32
Definition: common.h:158
Definition: d_bt.c:82
#define PLATFORM_END
Newest supported hardware (newer versions will use this)
Definition: lms2012.h:105
MODULE_SUPPORTED_DEVICE(DEVICE1_NAME)
Definition: am1808.h:36
Definition: am1808.h:38
#define PLATFORM_START
Oldest supported hardware (older versions will use this)
Definition: lms2012.h:104
#define NULL